Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
chkp_file.f90
Go to the documentation of this file.
1! Copyright (c) 2021-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 checkpoint, only : chkp_t
42 use num_types, only : rp, dp, i8
43 use field, only : field_t
44 use dofmap, only : dofmap_t
46 use space, only : space_t, gll
47 use mesh, only : mesh_t
48 use math, only : rzero
55 use mpi_f08, only : mpi_file, mpi_status, mpi_offset_kind, mpi_mode_create, &
56 mpi_mode_rdonly, mpi_mode_wronly, mpi_info_null, mpi_integer, &
57 mpi_double_precision, mpi_logical, mpi_success, &
58 mpi_file_open, mpi_file_close, mpi_file_read_all, mpi_file_write_all, &
59 mpi_file_read_at_all, mpi_file_write_at_all, mpi_bcast
60 implicit none
61 private
62
66 type(field_t), pointer :: u => null(), v => null(), w => null()
67 type(field_t), pointer :: p => null(), s => null()
69 type(field_t), pointer :: abx1 => null(), abx2 => null()
70 type(field_t), pointer :: aby1 => null(), aby2 => null()
71 type(field_t), pointer :: abz1 => null(), abz2 => null()
72 type(field_t), pointer :: abs1 => null(), abs2 => null()
74 type(field_t), pointer :: wm_x => null(), wm_y => null(), wm_z => null()
76 type(field_series_t), pointer :: ulag => null(), vlag => null()
77 type(field_series_t), pointer :: wlag => null(), slag => null()
78 type(field_series_t), pointer :: wm_x_lag => null()
79 type(field_series_t), pointer :: wm_y_lag => null()
80 type(field_series_t), pointer :: wm_z_lag => null()
82 real(kind=dp), pointer :: tlag(:) => null(), dtlag(:) => null()
84 real(kind=rp), pointer :: msh_x(:) => null(), msh_y(:) => null()
85 real(kind=rp), pointer :: msh_z(:) => null(), blag(:) => null()
86 real(kind=rp), pointer :: blaglag(:) => null()
88 real(kind=rp), pointer :: pivot_pos(:) => null()
89 real(kind=rp), pointer :: pivot_vel_lag(:) => null()
90 real(kind=rp), pointer :: basis_pos(:) => null()
91 real(kind=rp), pointer :: basis_vel_lag(:) => null()
93
95 type, public, extends(generic_file_t) :: chkp_file_t
97 type(space_t), pointer :: chkp_xh
99 type(space_t), pointer :: sim_xh
101 type(interpolator_t) :: space_interp
103 type(global_interpolation_t) :: global_interp
105 logical :: mesh2mesh
106 contains
108 procedure :: read => chkp_file_read
110 procedure :: read_field => chkp_read_field
112 procedure :: write => chkp_file_write
114 procedure :: get_next_output_fname => chkp_file_get_next_output_fname
116 procedure :: set_overwrite => chkp_file_set_overwrite
117 end type chkp_file_t
118
119contains
120
122 function chkp_file_get_next_output_fname(this) result(fname)
123 class(chkp_file_t), intent(in) :: this
124 character(len=1024) :: fname
125 character(len=5) :: id_str
126 integer :: counter, suffix_pos
127
128 if (this%overwrite) then
129 fname = this%get_fname()
130 else
131 counter = this%get_counter()
132 if (counter .eq. -1) then
133 counter = this%get_start_counter()
134 else
135 counter = counter + 1
136 end if
137
138 fname = this%get_base_fname()
139 suffix_pos = filename_suffix_pos(fname)
140 write(id_str, '(i5.5)') counter
141 fname = trim(fname(1:suffix_pos-1)) // id_str // fname(suffix_pos:)
142 end if
143
145
149 subroutine chkp_file_write(this, data, t)
150 class(chkp_file_t), intent(inout) :: this
151 class(*), target, intent(in) :: data
152 real(kind=dp), intent(in), optional :: t
153 real(kind=dp) :: time
154 character(len=5) :: id_str
155 character(len=1024) :: fname
156 integer :: ierr, suffix_pos, optional_fields
157 type(field_t), pointer :: u, v, w, p, s
158 type(field_t), pointer :: wm_x => null()
159 type(field_t), pointer :: wm_y => null()
160 type(field_t), pointer :: wm_z => null()
161 type(field_t), pointer :: abx1, abx2
162 type(field_t), pointer :: aby1, aby2
163 type(field_t), pointer :: abz1, abz2
164 type(field_t), pointer :: abs1, abs2
165 type(field_series_t), pointer :: ulag => null()
166 type(field_series_t), pointer :: vlag => null()
167 type(field_series_t), pointer :: wlag => null()
168 type(field_series_t), pointer :: wm_x_lag => null()
169 type(field_series_t), pointer :: wm_y_lag => null()
170 type(field_series_t), pointer :: wm_z_lag => null()
171 type(field_series_t), pointer :: slag => null()
172 real(kind=rp), pointer :: msh_x(:) => null()
173 real(kind=rp), pointer :: msh_y(:) => null()
174 real(kind=rp), pointer :: msh_z(:) => null()
175 real(kind=rp), pointer :: blag(:) => null()
176 real(kind=rp), pointer :: blaglag(:) => null()
177 real(kind=rp), pointer :: pivot_pos(:) => null()
178 real(kind=rp), pointer :: pivot_vel_lag(:) => null()
179 real(kind=rp), pointer :: basis_pos(:) => null()
180 real(kind=rp), pointer :: basis_vel_lag(:) => null()
181 real(kind=dp), pointer :: dtlag(:), tlag(:)
182 type(mesh_t), pointer :: msh
183 type(mpi_status) :: status
184 type(mpi_file) :: fh
185 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
186 integer(kind=i8) :: n_glb_dofs, dof_offset
187 logical :: write_lag, write_scalar, write_dtlag
188 logical :: write_ale
189 logical :: write_scalarlag, write_abvel
190 integer :: i
191 type(legacy_checkpoint_view_t) :: view
192
193 if (present(t)) then
194 time = t
195 else
196 time = 0.0_dp
197 end if
198
199 select type (data)
200 type is (chkp_t)
201
202 if (data%scalar_payload_count() .gt. 1) then
203 call neko_error("The legacy .chkp format supports at most one " // &
204 "scalar; use HDF5 checkpointing for multiple scalars")
205 end if
206
207 call chkp_build_legacy_view(data, view)
208 if ( .not. associated(view%u) .or. &
209 .not. associated(view%v) .or. &
210 .not. associated(view%w) .or. &
211 .not. associated(view%p) ) then
212 call neko_error('Checkpoint not initialized')
213 end if
214
215 u => view%u
216 v => view%v
217 w => view%w
218 p => view%p
219 msh => u%msh
220
221 optional_fields = 0
222
223 if (associated(view%ulag)) then
224 ulag => view%ulag
225 vlag => view%vlag
226 wlag => view%wlag
227 write_lag = .true.
228 optional_fields = optional_fields + 1
229 else
230 write_lag = .false.
231 end if
232
233 if (associated(view%s)) then
234 s => view%s
235 write_scalar = .true.
236 optional_fields = optional_fields + 2
237 else
238 write_scalar = .false.
239 end if
240
241 if (associated(view%tlag)) then
242 tlag => view%tlag
243 dtlag => view%dtlag
244 write_dtlag = .true.
245 optional_fields = optional_fields + 4
246 else
247 write_dtlag = .false.
248 end if
249
250 write_abvel = .false.
251 if (associated(view%abx1)) then
252 abx1 => view%abx1
253 abx2 => view%abx2
254 aby1 => view%aby1
255 aby2 => view%aby2
256 abz1 => view%abz1
257 abz2 => view%abz2
258 optional_fields = optional_fields + 8
259 write_abvel = .true.
260 end if
261
262 write_scalarlag = .false.
263 if (associated(view%abs1)) then
264 slag => view%slag
265 abs1 => view%abs1
266 abs2 => view%abs2
267 optional_fields = optional_fields + 16
268 write_scalarlag = .true.
269 end if
270
271 write_ale = .false.
272 if (associated(view%wm_x)) then
273 msh_x => view%msh_x
274 msh_y => view%msh_y
275 msh_z => view%msh_z
276 wm_x => view%wm_x
277 wm_y => view%wm_y
278 wm_z => view%wm_z
279 wm_x_lag => view%wm_x_lag
280 wm_y_lag => view%wm_y_lag
281 wm_z_lag => view%wm_z_lag
282 blag => view%Blag
283 blaglag => view%Blaglag
284 pivot_pos => view%pivot_pos
285 pivot_vel_lag => view%pivot_vel_lag
286 basis_pos => view%basis_pos
287 basis_vel_lag => view%basis_vel_lag
288 optional_fields = optional_fields + 32
289 write_ale = .true.
290 end if
291
292 class default
293 call neko_error('Invalid data')
294 end select
295
296 dof_offset = int(msh%offset_el, i8) * int(u%Xh%lx * u%Xh%ly * u%Xh%lz, i8)
297 n_glb_dofs = int(u%Xh%lx * u%Xh%ly * u%Xh%lz, i8) * int(msh%glb_nelv, i8)
298
299 ! Retrieve the filename and increment the counter if we are not overwriting
300 if (.not. this%overwrite) call this%increment_counter()
301 fname = trim(this%get_fname())
302
303 call mpi_file_open(neko_comm, trim(fname), &
304 mpi_mode_wronly + mpi_mode_create, mpi_info_null, fh, ierr)
305 call mpi_file_write_all(fh, msh%glb_nelv, 1, mpi_integer, status, ierr)
306 call mpi_file_write_all(fh, msh%gdim, 1, mpi_integer, status, ierr)
307 call mpi_file_write_all(fh, u%Xh%lx, 1, mpi_integer, status, ierr)
308 call mpi_file_write_all(fh, optional_fields, 1, mpi_integer, status, ierr)
309 call mpi_file_write_all(fh, time, 1, mpi_double_precision, status, ierr)
310
311
312 !
313 ! Dump mandatory checkpoint data
314 !
315
316 byte_offset = 4_i8 * int(mpi_integer_size, i8) + &
318 byte_offset = byte_offset + &
319 dof_offset * int(mpi_real_prec_size, i8)
320 call mpi_file_write_at_all(fh, byte_offset,u%x, u%dof%size(), &
321 mpi_real_precision, status, ierr)
322 mpi_offset = 4_i8 * int(mpi_integer_size, i8) + &
324 mpi_offset = mpi_offset +&
325 n_glb_dofs * int(mpi_real_prec_size, i8)
326
327 byte_offset = mpi_offset + &
328 dof_offset * int(mpi_real_prec_size, i8)
329 call mpi_file_write_at_all(fh, byte_offset, v%x, v%dof%size(), &
330 mpi_real_precision, status, ierr)
331 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
332
333 byte_offset = mpi_offset + &
334 dof_offset * int(mpi_real_prec_size, i8)
335 call mpi_file_write_at_all(fh, byte_offset, w%x, w%dof%size(), &
336 mpi_real_precision, status, ierr)
337 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
338
339 byte_offset = mpi_offset + &
340 dof_offset * int(mpi_real_prec_size, i8)
341 call mpi_file_write_at_all(fh, byte_offset, p%x, p%dof%size(), &
342 mpi_real_precision, status, ierr)
343 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
344
345 !
346 ! Dump optional payload
347 !
348
349 if (write_lag) then
350
351 do i = 1, ulag%size()
352 byte_offset = mpi_offset + &
353 dof_offset * int(mpi_real_prec_size, i8)
354 ! We should not need this extra associate block, and it works
355 ! great without it for GNU, Intel, NEC and Cray, but throws an
356 ! ICE with NAG.
357 associate(x => ulag%lf(i)%x)
358 call mpi_file_write_at_all(fh, byte_offset, x, &
359 ulag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
360 end associate
361 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
362 end do
363
364 do i = 1, vlag%size()
365 byte_offset = mpi_offset + &
366 dof_offset * int(mpi_real_prec_size, i8)
367 ! We should not need this extra associate block, and it works
368 ! great without it for GNU, Intel, NEC and Cray, but throws an
369 ! ICE with NAG.
370 associate(x => vlag%lf(i)%x)
371 call mpi_file_write_at_all(fh, byte_offset, x, &
372 vlag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
373 end associate
374 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
375 end do
376
377 do i = 1, wlag%size()
378 byte_offset = mpi_offset + &
379 dof_offset * int(mpi_real_prec_size, i8)
380 ! We should not need this extra associate block, and it works
381 ! great without it for GNU, Intel, NEC and Cray, but throws an
382 ! ICE with NAG.
383 associate(x => wlag%lf(i)%x)
384 call mpi_file_write_at_all(fh, byte_offset, x, &
385 wlag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
386 end associate
387 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
388 end do
389
390 end if
391
392 if (write_scalar) then
393 byte_offset = mpi_offset + &
394 dof_offset * int(mpi_real_prec_size, i8)
395 call mpi_file_write_at_all(fh, byte_offset, s%x, p%dof%size(), &
396 mpi_real_precision, status, ierr)
397 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
398 end if
399
400 if (write_dtlag) then
401 call mpi_file_write_at_all(fh, mpi_offset, tlag, 10, &
402 mpi_double_precision, status, ierr)
403 mpi_offset = mpi_offset + 10_i8 * int(mpi_double_precision_size, i8)
404 call mpi_file_write_at_all(fh, mpi_offset, dtlag, 10, &
405 mpi_double_precision, status, ierr)
406 mpi_offset = mpi_offset + 10_i8 * int(mpi_double_precision_size, i8)
407 end if
408
409 if (write_abvel) then
410 byte_offset = mpi_offset + &
411 dof_offset * int(mpi_real_prec_size, i8)
412 call mpi_file_write_at_all(fh, byte_offset, abx1%x, abx1%dof%size(), &
413 mpi_real_precision, status, ierr)
414 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
415 byte_offset = mpi_offset + &
416 dof_offset * int(mpi_real_prec_size, i8)
417 call mpi_file_write_at_all(fh, byte_offset, abx2%x, abx1%dof%size(), &
418 mpi_real_precision, status, ierr)
419 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
420 byte_offset = mpi_offset + &
421 dof_offset * int(mpi_real_prec_size, i8)
422 call mpi_file_write_at_all(fh, byte_offset, aby1%x, abx1%dof%size(), &
423 mpi_real_precision, status, ierr)
424 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
425 byte_offset = mpi_offset + &
426 dof_offset * int(mpi_real_prec_size, i8)
427 call mpi_file_write_at_all(fh, byte_offset, aby2%x, abx1%dof%size(), &
428 mpi_real_precision, status, ierr)
429 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
430 byte_offset = mpi_offset + &
431 dof_offset * int(mpi_real_prec_size, i8)
432 call mpi_file_write_at_all(fh, byte_offset, abz1%x, abx1%dof%size(), &
433 mpi_real_precision, status, ierr)
434 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
435 byte_offset = mpi_offset + &
436 dof_offset * int(mpi_real_prec_size, i8)
437 call mpi_file_write_at_all(fh, byte_offset, abz2%x, abx1%dof%size(), &
438 mpi_real_precision, status, ierr)
439 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
440 end if
441
442 if (write_scalarlag) then
443 do i = 1, slag%size()
444 byte_offset = mpi_offset + &
445 dof_offset * int(mpi_real_prec_size, i8)
446 ! We should not need this extra associate block, and it works
447 ! great without it for GNU, Intel, NEC and Cray, but throws an
448 ! ICE with NAG.
449 associate(x => slag%lf(i)%x)
450 call mpi_file_write_at_all(fh, byte_offset, x, &
451 slag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
452 end associate
453 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
454 end do
455
456 byte_offset = mpi_offset + &
457 dof_offset * int(mpi_real_prec_size, i8)
458 call mpi_file_write_at_all(fh, byte_offset, abs1%x, abx1%dof%size(), &
459 mpi_real_precision, status, ierr)
460 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
461 byte_offset = mpi_offset + &
462 dof_offset * int(mpi_real_prec_size, i8)
463 call mpi_file_write_at_all(fh, byte_offset, abs2%x, abx1%dof%size(), &
464 mpi_real_precision, status, ierr)
465 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
466 end if
467
468 if (write_ale) then
469 byte_offset = mpi_offset + &
470 dof_offset * int(mpi_real_prec_size, i8)
471 call mpi_file_write_at_all(fh, byte_offset, msh_x, size(msh_x), &
472 mpi_real_precision, status, ierr)
473 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
474
475 byte_offset = mpi_offset + &
476 dof_offset * int(mpi_real_prec_size, i8)
477 call mpi_file_write_at_all(fh, byte_offset, msh_y, size(msh_y), &
478 mpi_real_precision, status, ierr)
479 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
480
481 byte_offset = mpi_offset + &
482 dof_offset * int(mpi_real_prec_size, i8)
483 call mpi_file_write_at_all(fh, byte_offset, msh_z, size(msh_z), &
484 mpi_real_precision, status, ierr)
485 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
486
487 byte_offset = mpi_offset + &
488 dof_offset * int(mpi_real_prec_size, i8)
489 call mpi_file_write_at_all(fh, byte_offset, wm_x%x, wm_x%dof%size(), &
490 mpi_real_precision, status, ierr)
491 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
492
493 byte_offset = mpi_offset + &
494 dof_offset * int(mpi_real_prec_size, i8)
495 call mpi_file_write_at_all(fh, byte_offset, wm_y%x, wm_y%dof%size(), &
496 mpi_real_precision, status, ierr)
497 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
498
499 byte_offset = mpi_offset + &
500 dof_offset * int(mpi_real_prec_size, i8)
501 call mpi_file_write_at_all(fh, byte_offset, wm_z%x, wm_z%dof%size(), &
502 mpi_real_precision, status, ierr)
503 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
504
505 do i = 1, wm_x_lag%size()
506 byte_offset = mpi_offset + &
507 dof_offset * int(mpi_real_prec_size, i8)
508 ! We should not need this extra associate block, and it works
509 ! great without it for GNU, Intel, NEC and Cray, but throws an
510 ! ICE with NAG.
511 associate(x => wm_x_lag%lf(i)%x)
512 call mpi_file_write_at_all(fh, byte_offset, x, &
513 wm_x_lag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
514 end associate
515 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
516 end do
517
518 do i = 1, wm_y_lag%size()
519 byte_offset = mpi_offset + &
520 dof_offset * int(mpi_real_prec_size, i8)
521 ! We should not need this extra associate block, and it works
522 ! great without it for GNU, Intel, NEC and Cray, but throws an
523 ! ICE with NAG.
524 associate(x => wm_y_lag%lf(i)%x)
525 call mpi_file_write_at_all(fh, byte_offset, x, &
526 wm_y_lag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
527 end associate
528 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
529 end do
530
531 do i = 1, wm_z_lag%size()
532 byte_offset = mpi_offset + &
533 dof_offset * int(mpi_real_prec_size, i8)
534 ! We should not need this extra associate block, and it works
535 ! great without it for GNU, Intel, NEC and Cray, but throws an
536 ! ICE with NAG.
537 associate(x => wm_z_lag%lf(i)%x)
538 call mpi_file_write_at_all(fh, byte_offset, x, &
539 wm_z_lag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
540 end associate
541 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
542 end do
543
544 byte_offset = mpi_offset + &
545 dof_offset * int(mpi_real_prec_size, i8)
546 call mpi_file_write_at_all(fh, byte_offset, blag, size(blag), &
547 mpi_real_precision, status, ierr)
548 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
549
550 byte_offset = mpi_offset + &
551 dof_offset * int(mpi_real_prec_size, i8)
552 call mpi_file_write_at_all(fh, byte_offset, blaglag, size(blaglag), &
553 mpi_real_precision, status, ierr)
554 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
555
556 call mpi_file_write_at_all(fh, mpi_offset, pivot_pos, size(pivot_pos), &
557 mpi_real_precision, status, ierr)
558 mpi_offset = mpi_offset + &
559 int(size(pivot_pos), i8) * int(mpi_real_prec_size, i8)
560 call mpi_file_write_at_all(fh, mpi_offset, pivot_vel_lag, &
561 size(pivot_vel_lag), mpi_real_precision, status, ierr)
562 mpi_offset = mpi_offset + &
563 int(size(pivot_vel_lag), i8) * int(mpi_real_prec_size, i8)
564 call mpi_file_write_at_all(fh, mpi_offset, basis_pos, &
565 size(basis_pos), mpi_real_precision, status, ierr)
566 mpi_offset = mpi_offset + &
567 int(size(basis_pos), i8) * int(mpi_real_prec_size, i8)
568 call mpi_file_write_at_all(fh, mpi_offset, basis_vel_lag, &
569 size(basis_vel_lag), mpi_real_precision, status, ierr)
570 mpi_offset = mpi_offset + &
571 int(size(basis_vel_lag), i8) * int(mpi_real_prec_size, i8)
572 end if
573
574 call mpi_file_close(fh, ierr)
575
576 if (ierr .ne. mpi_success) then
577 call neko_error('Error writing checkpoint file ' // trim(fname))
578 end if
579
580 end subroutine chkp_file_write
581
584 subroutine chkp_file_read(this, data)
585 class(chkp_file_t) :: this
586 class(*), target, intent(inout) :: data
587 type(chkp_t), pointer :: chkp
588 character(len=5) :: id_str
589 character(len=1024) :: fname
590 integer :: ierr, suffix_pos
591 type(field_t), pointer :: u, v, w, p, s
592 type(field_t), pointer :: wm_x => null()
593 type(field_t), pointer :: wm_y => null()
594 type(field_t), pointer :: wm_z => null()
595 type(field_series_t), pointer :: ulag => null()
596 type(field_series_t), pointer :: vlag => null()
597 type(field_series_t), pointer :: wlag => null()
598 type(field_series_t), pointer :: wm_x_lag => null()
599 type(field_series_t), pointer :: wm_y_lag => null()
600 type(field_series_t), pointer :: wm_z_lag => null()
601 type(field_series_t), pointer :: slag => null()
602 type(mesh_t), pointer :: msh
603 type(mpi_status) :: status
604 type(mpi_file) :: fh
605 type(field_t), pointer :: abx1, abx2
606 type(field_t), pointer :: aby1, aby2
607 type(field_t), pointer :: abz1, abz2
608 type(field_t), pointer :: abs1, abs2
609 real(kind=rp), pointer :: blag(:) => null()
610 real(kind=rp), pointer :: blaglag(:) => null()
611 real(kind=rp), pointer :: msh_x(:) => null()
612 real(kind=rp), pointer :: msh_y(:) => null()
613 real(kind=rp), pointer :: msh_z(:) => null()
614 real(kind=rp), pointer :: pivot_pos(:) => null()
615 real(kind=rp), pointer :: pivot_vel_lag(:) => null()
616 real(kind=rp), pointer :: basis_pos(:) => null()
617 real(kind=rp), pointer :: basis_vel_lag(:) => null()
618 real(kind=rp), allocatable :: x_coord(:,:,:,:)
619 real(kind=rp), allocatable :: y_coord(:,:,:,:)
620 real(kind=rp), allocatable :: z_coord(:,:,:,:)
621 real(kind=dp), pointer :: dtlag(:), tlag(:)
622 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
623 integer(kind=i8) :: n_glb_dofs, dof_offset
624 integer :: glb_nelv, gdim, lx, have_lag, have_scalar, nel
625 integer :: optional_fields, have_dtlag
626 integer :: have_abvel, have_scalarlag
627 integer :: have_ale
628 logical :: read_lag, read_scalar, read_dtlag, read_abvel, read_scalarlag
629 logical :: read_ale
630 real(kind=dp) :: tol
631 real(kind=rp) :: center_x, center_y, center_z
632 integer :: i, e
633 type(dofmap_t) :: dof
634 type(legacy_checkpoint_view_t) :: view
635
636 call this%check_exists()
637
638 select type (data)
639 type is (chkp_t)
640
641 if (data%scalar_payload_count() .gt. 1) then
642 call neko_error("The legacy .chkp format supports at most one " // &
643 "scalar; use HDF5 checkpointing for multiple scalars")
644 end if
645
646 call chkp_build_legacy_view(data, view)
647 if ( .not. associated(view%u) .or. &
648 .not. associated(view%v) .or. &
649 .not. associated(view%w) .or. &
650 .not. associated(view%p) ) then
651 call neko_error('Checkpoint not initialized')
652 end if
653
654 u => view%u
655 v => view%v
656 w => view%w
657 p => view%p
658 this%chkp_Xh => data%previous_Xh
660 if (allocated(data%previous_mesh%elements)) then
661 msh => data%previous_mesh
662 this%mesh2mesh = .true.
663 tol = data%mesh2mesh_tol
664 else
665 msh => u%msh
666 this%mesh2mesh = .false.
667 end if
668
669 if (associated(view%ulag)) then
670 ulag => view%ulag
671 vlag => view%vlag
672 wlag => view%wlag
673 read_lag = .true.
674 else
675 read_lag = .false.
676 end if
677
678 if (associated(view%s)) then
679 s => view%s
680 read_scalar = .true.
681 else
682 read_scalar = .false.
683 end if
684 if (associated(view%dtlag)) then
685 dtlag => view%dtlag
686 tlag => view%tlag
687 read_dtlag = .true.
688 else
689 read_dtlag = .false.
690 end if
691 read_abvel = .false.
692 if (associated(view%abx1)) then
693 abx1 => view%abx1
694 abx2 => view%abx2
695 aby1 => view%aby1
696 aby2 => view%aby2
697 abz1 => view%abz1
698 abz2 => view%abz2
699 read_abvel = .true.
700 end if
701 read_scalarlag = .false.
702 if (associated(view%abs1)) then
703 slag => view%slag
704 abs1 => view%abs1
705 abs2 => view%abs2
706 read_scalarlag = .true.
707 end if
708
709 read_ale = .false.
710 if (associated(view%wm_x)) then
711 msh_x => view%msh_x
712 msh_y => view%msh_y
713 msh_z => view%msh_z
714 wm_x => view%wm_x
715 wm_y => view%wm_y
716 wm_z => view%wm_z
717 wm_x_lag => view%wm_x_lag
718 wm_y_lag => view%wm_y_lag
719 wm_z_lag => view%wm_z_lag
720 blag => view%Blag
721 blaglag => view%Blaglag
722 pivot_pos => view%pivot_pos
723 pivot_vel_lag => view%pivot_vel_lag
724 basis_pos => view%basis_pos
725 basis_vel_lag => view%basis_vel_lag
726 read_ale = .true.
727 end if
728
729 chkp => data
730
731 class default
732 call neko_error('Invalid data')
733 end select
734
735 fname = trim(this%get_fname())
736 call neko_log%message("Reading checkpoint from file: " // trim(fname), &
737 neko_log_verbose)
738 call mpi_file_open(neko_comm, trim(fname), &
739 mpi_mode_rdonly, mpi_info_null, fh, ierr)
740 call mpi_file_read_all(fh, glb_nelv, 1, mpi_integer, status, ierr)
741 call mpi_file_read_all(fh, gdim, 1, mpi_integer, status, ierr)
742 call mpi_file_read_all(fh, lx, 1, mpi_integer, status, ierr)
743 call mpi_file_read_all(fh, optional_fields, 1, mpi_integer, status, ierr)
744 call mpi_file_read_all(fh, chkp%t, 1, mpi_double_precision, status, ierr)
745
746 have_lag = mod(optional_fields,2)/1
747 have_scalar = mod(optional_fields,4)/2
748 have_dtlag = mod(optional_fields,8)/4
749 have_abvel = mod(optional_fields,16)/8
750 have_scalarlag = mod(optional_fields,32)/16
751 have_ale = mod(optional_fields,64)/32
752
753 if ( ( glb_nelv .ne. msh%glb_nelv ) .or. &
754 ( gdim .ne. msh%gdim) .or. &
755 ( (have_lag .eq. 0) .and. (read_lag) ) .or. &
756 ( (have_scalar .eq. 0) .and. (read_scalar) ) .or. &
757 ( (have_ale .eq. 0) .and. (read_ale) ) ) then
758 call neko_error('Checkpoint does not match case')
759 end if
760 nel = msh%nelv
761 this%sim_Xh => u%Xh
762 if (gdim .eq. 3) then
763 call this%chkp_Xh%init(gll, lx, lx, lx)
764 else
765 call this%chkp_Xh%init(gll, lx, lx)
766 end if
767 if (this%mesh2mesh) then
768 if (read_ale) then
769 call neko_error('ALE does not yet support mesh2mesh ' // &
770 'interpolation for restart!')
771 end if
772 call dof%init(msh, this%chkp_Xh)
773 call this%global_interp%init(dof, neko_comm, tol = tol)
774 call this%global_interp%find_points(u%dof%x%x, u%dof%y%x, u%dof%z%x, &
775 u%dof%size())
776 else
777 call this%space_interp%init(this%sim_Xh, this%chkp_Xh)
778 end if
779 dof_offset = int(msh%offset_el, i8) * int(this%chkp_Xh%lxyz, i8)
780 n_glb_dofs = int(this%chkp_Xh%lxyz, i8) * int(msh%glb_nelv, i8)
781
782 !
783 ! Read mandatory checkpoint data
784 !
785
786 byte_offset = 4_i8 * int(mpi_integer_size, i8) + &
787 int(mpi_double_precision_size, i8)
788 byte_offset = byte_offset + &
789 dof_offset * int(mpi_real_prec_size, i8)
790 call this%read_field(fh, byte_offset, u%x, nel)
791 mpi_offset = 4_i8 * int(mpi_integer_size, i8) + &
792 int(mpi_double_precision_size, i8)
793 mpi_offset = mpi_offset +&
794 n_glb_dofs * int(mpi_real_prec_size, i8)
795
796 byte_offset = mpi_offset + &
797 dof_offset * int(mpi_real_prec_size, i8)
798 call this%read_field(fh, byte_offset, v%x, nel)
799 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
800
801 byte_offset = mpi_offset + &
802 dof_offset * int(mpi_real_prec_size, i8)
803 call this%read_field(fh, byte_offset, w%x, nel)
804 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
805
806 byte_offset = mpi_offset + &
807 dof_offset * int(mpi_real_prec_size, i8)
808 call this%read_field(fh, byte_offset, p%x, nel)
809 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
810
811 !
812 ! Read optional payload
813 !
814
815 if (read_lag) then
816 do i = 1, ulag%size()
817 byte_offset = mpi_offset + &
818 dof_offset * int(mpi_real_prec_size, i8)
819 call this%read_field(fh, byte_offset, ulag%lf(i)%x, nel)
820 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
821 end do
822
823 do i = 1, vlag%size()
824 byte_offset = mpi_offset + &
825 dof_offset * int(mpi_real_prec_size, i8)
826 call this%read_field(fh, byte_offset, vlag%lf(i)%x, nel)
827 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
828 end do
829
830 do i = 1, wlag%size()
831 byte_offset = mpi_offset + &
832 dof_offset * int(mpi_real_prec_size, i8)
833 call this%read_field(fh, byte_offset, wlag%lf(i)%x, nel)
834 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
835 end do
836 end if
837
838 if (read_scalar) then
839 byte_offset = mpi_offset + &
840 dof_offset * int(mpi_real_prec_size, i8)
841 call this%read_field(fh, byte_offset, s%x, nel)
842 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
843 end if
844
845 if (read_dtlag .and. have_dtlag .eq. 1) then
846 call mpi_file_read_at_all(fh, mpi_offset, tlag, 10, &
847 mpi_double_precision, status, ierr)
848 mpi_offset = mpi_offset + 10_i8 * int(mpi_double_precision_size, i8)
849 call mpi_file_read_at_all(fh, mpi_offset, dtlag, 10, &
850 mpi_double_precision, status, ierr)
851 mpi_offset = mpi_offset + 10_i8 * int(mpi_double_precision_size, i8)
852 end if
853
854 if (read_abvel .and. have_abvel .eq. 1) then
855 byte_offset = mpi_offset + &
856 dof_offset * int(mpi_real_prec_size, i8)
857 call this%read_field(fh, byte_offset, abx1%x, nel)
858 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
859 byte_offset = mpi_offset + &
860 dof_offset * int(mpi_real_prec_size, i8)
861 call this%read_field(fh, byte_offset, abx2%x, nel)
862 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
863 byte_offset = mpi_offset + &
864 dof_offset * int(mpi_real_prec_size, i8)
865 call this%read_field(fh, byte_offset, aby1%x, nel)
866 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
867 byte_offset = mpi_offset + &
868 dof_offset * int(mpi_real_prec_size, i8)
869 call this%read_field(fh, byte_offset, aby2%x, nel)
870 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
871 byte_offset = mpi_offset + &
872 dof_offset * int(mpi_real_prec_size, i8)
873 call this%read_field(fh, byte_offset, abz1%x, nel)
874 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
875 byte_offset = mpi_offset + &
876 dof_offset * int(mpi_real_prec_size, i8)
877 call this%read_field(fh, byte_offset, abz2%x, nel)
878 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
879 end if
880 if (read_scalarlag .and. have_scalarlag .eq. 1) then
881 do i = 1, slag%size()
882 byte_offset = mpi_offset + &
883 dof_offset * int(mpi_real_prec_size, i8)
884 call this%read_field(fh, byte_offset, slag%lf(i)%x, nel)
885 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
886 end do
887 byte_offset = mpi_offset + &
888 dof_offset * int(mpi_real_prec_size, i8)
889 call this%read_field(fh, byte_offset, abs1%x, nel)
890 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
891 byte_offset = mpi_offset + &
892 dof_offset * int(mpi_real_prec_size, i8)
893 call this%read_field(fh, byte_offset, abs2%x, nel)
894 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
895 end if
896
897 if (read_ale .and. have_ale .eq. 1) then
898
899 byte_offset = mpi_offset + &
900 dof_offset * int(mpi_real_prec_size, i8)
901 call this%read_field(fh, byte_offset, msh_x, nel)
902 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
903
904 byte_offset = mpi_offset + &
905 dof_offset * int(mpi_real_prec_size, i8)
906 call this%read_field(fh, byte_offset, msh_y, nel)
907 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
908
909 byte_offset = mpi_offset + &
910 dof_offset * int(mpi_real_prec_size, i8)
911 call this%read_field(fh, byte_offset, msh_z, nel)
912 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
913
914 byte_offset = mpi_offset + &
915 dof_offset * int(mpi_real_prec_size, i8)
916 call this%read_field(fh, byte_offset, wm_x%x, nel)
917 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
918
919 byte_offset = mpi_offset + &
920 dof_offset * int(mpi_real_prec_size, i8)
921 call this%read_field(fh, byte_offset, wm_y%x, nel)
922 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
923
924 byte_offset = mpi_offset + &
925 dof_offset * int(mpi_real_prec_size, i8)
926 call this%read_field(fh, byte_offset, wm_z%x, nel)
927 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
928
929 do i = 1, wm_x_lag%size()
930 byte_offset = mpi_offset + &
931 dof_offset * int(mpi_real_prec_size, i8)
932 call this%read_field(fh, byte_offset, wm_x_lag%lf(i)%x, nel)
933 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
934 end do
935 do i = 1, wm_y_lag%size()
936 byte_offset = mpi_offset + &
937 dof_offset * int(mpi_real_prec_size, i8)
938 call this%read_field(fh, byte_offset, wm_y_lag%lf(i)%x, nel)
939 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
940 end do
941 do i = 1, wm_z_lag%size()
942 byte_offset = mpi_offset + &
943 dof_offset * int(mpi_real_prec_size, i8)
944 call this%read_field(fh, byte_offset, wm_z_lag%lf(i)%x, nel)
945 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
946 end do
947 byte_offset = mpi_offset + &
948 dof_offset * int(mpi_real_prec_size, i8)
949 call this%read_field(fh, byte_offset, blag, nel)
950 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
951
952 byte_offset = mpi_offset + &
953 dof_offset * int(mpi_real_prec_size, i8)
954 call this%read_field(fh, byte_offset, blaglag, nel)
955 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
956
957 call mpi_file_read_at_all(fh, mpi_offset, pivot_pos, &
958 size(pivot_pos), mpi_real_precision, status, ierr)
959 mpi_offset = mpi_offset + int(size(pivot_pos), i8) &
960 * int(mpi_real_prec_size, i8)
961
962 call mpi_file_read_at_all(fh, mpi_offset, pivot_vel_lag, &
963 size(pivot_vel_lag), mpi_real_precision, status, ierr)
964 mpi_offset = mpi_offset + int(size(pivot_vel_lag), i8) &
965 * int(mpi_real_prec_size, i8)
966
967 call mpi_file_read_at_all(fh, mpi_offset, basis_pos, &
968 size(basis_pos), mpi_real_precision, status, ierr)
969 mpi_offset = mpi_offset + &
970 int(size(basis_pos), i8) * int(mpi_real_prec_size, i8)
971
972 call mpi_file_read_at_all(fh, mpi_offset, basis_vel_lag, &
973 size(basis_vel_lag), mpi_real_precision, status, ierr)
974 mpi_offset = mpi_offset + &
975 int(size(basis_vel_lag), i8) * int(mpi_real_prec_size, i8)
976 end if
977
978
979 call mpi_file_close(fh, ierr)
980
981 if (ierr .ne. mpi_success) then
982 call neko_error('Error reading checkpoint file ' // trim(fname))
983 end if
984
985 call this%global_interp%free()
986 call this%space_interp%free()
987
988 end subroutine chkp_file_read
989
995 subroutine chkp_read_field(this, fh, byte_offset, x, nel)
996 class(chkp_file_t) :: this
997 type(mpi_file) :: fh
998 integer(kind=MPI_OFFSET_KIND) :: byte_offset
999 integer, intent(in) :: nel
1000 real(kind=rp) :: x(this%sim_Xh%lxyz, nel)
1001 real(kind=rp), allocatable :: read_array(:)
1002 integer :: nel_stride, frac_space
1003 type(mpi_status) :: status
1004 integer :: ierr, i, n
1005 logical :: interp_on_host = .true.
1006
1007 n = this%chkp_xh%lxyz*nel
1008 allocate(read_array(n))
1009
1010 call rzero(read_array,n)
1011 call mpi_file_read_at_all(fh, byte_offset, read_array, &
1012 n, mpi_real_precision, status, ierr)
1013 if (this%mesh2mesh) then
1014 x = 0.0_rp
1015 call this%global_interp%evaluate(x, read_array, interp_on_host)
1016
1017 else if (this%sim_Xh%lx .ne. this%chkp_Xh%lx) then
1018 call this%space_interp%map_host(x, read_array, nel, this%sim_Xh)
1019 else
1020 do i = 1,n
1021 x(i,1) = read_array(i)
1022 end do
1023 end if
1024 deallocate(read_array)
1025 end subroutine chkp_read_field
1026
1030 subroutine chkp_build_legacy_view(chkp, view)
1031 type(chkp_t), intent(in) :: chkp
1032 type(legacy_checkpoint_view_t), intent(out) :: view
1033 type(checkpoint_payload_t), pointer :: payload
1034 type(checkpoint_array_t), pointer :: array
1035 type(checkpoint_mesh_array_t), pointer :: mesh_array
1036 character(len=:), allocatable :: scalar_name
1037 integer :: i
1038
1039 payload => chkp_find_payload(chkp, "fluid")
1040 if (.not. associated(payload)) then
1041 call neko_error("Checkpoint not initialized")
1042 end if
1043 view%u => payload%find_field("u")
1044 view%v => payload%find_field("v")
1045 view%w => payload%find_field("w")
1046 view%p => payload%find_field("p")
1047 view%abx1 => payload%find_field("abx1")
1048 view%abx2 => payload%find_field("abx2")
1049 view%aby1 => payload%find_field("aby1")
1050 view%aby2 => payload%find_field("aby2")
1051 view%abz1 => payload%find_field("abz1")
1052 view%abz2 => payload%find_field("abz2")
1053 view%ulag => payload%find_series("u")
1054 view%vlag => payload%find_series("v")
1055 view%wlag => payload%find_series("w")
1056
1057 call chkp%get_time_history(view%tlag, view%dtlag)
1058
1059 ! Only one scalar assumed, we grab the first one we find.
1060 do i = 1, chkp%payload_count()
1061 if (index(trim(chkp%payloads(i)%ptr%name), "scalars/") .eq. 1) then
1062 payload => chkp%payloads(i)%ptr
1063 scalar_name = payload%name(len("scalars/") + 1:)
1064 view%s => payload%find_field(scalar_name)
1065 view%slag => payload%find_series(scalar_name)
1066 view%abs1 => payload%find_field(trim(scalar_name) // "_abx1")
1067 view%abs2 => payload%find_field(trim(scalar_name) // "_abx2")
1068 exit
1069 end if
1070 end do
1071
1072 payload => chkp_find_payload(chkp, "ale")
1073 if (.not. associated(payload)) return
1074
1075 view%wm_x => payload%find_field("wm_x")
1076 view%wm_y => payload%find_field("wm_y")
1077 view%wm_z => payload%find_field("wm_z")
1078 view%wm_x_lag => payload%find_series("wm_x")
1079 view%wm_y_lag => payload%find_series("wm_y")
1080 view%wm_z_lag => payload%find_series("wm_z")
1081
1082 mesh_array => payload%find_mesh_array("mesh_x")
1083 if (associated(mesh_array)) view%msh_x => mesh_array%x
1084 mesh_array => payload%find_mesh_array("mesh_y")
1085 if (associated(mesh_array)) view%msh_y => mesh_array%x
1086 mesh_array => payload%find_mesh_array("mesh_z")
1087 if (associated(mesh_array)) view%msh_z => mesh_array%x
1088 mesh_array => payload%find_mesh_array("B_lag")
1089 if (associated(mesh_array)) view%Blag => mesh_array%x
1090 mesh_array => payload%find_mesh_array("B_laglag")
1091 if (associated(mesh_array)) view%Blaglag => mesh_array%x
1092 array => payload%find_array("pivot_position")
1093 if (associated(array)) view%pivot_pos => array%x
1094 array => payload%find_array("pivot_velocity_lag")
1095 if (associated(array)) view%pivot_vel_lag => array%x
1096 array => payload%find_array("basis_position")
1097 if (associated(array)) view%basis_pos => array%x
1098 array => payload%find_array("basis_velocity_lag")
1099 if (associated(array)) view%basis_vel_lag => array%x
1100
1101 end subroutine chkp_build_legacy_view
1102
1107 function chkp_find_payload(chkp, name) result(payload)
1108 type(chkp_t), intent(in) :: chkp
1109 character(len=*), intent(in) :: name
1110 type(checkpoint_payload_t), pointer :: payload
1111 integer :: i
1112
1113 nullify(payload)
1114 do i = 1, chkp%payload_count()
1115 if (trim(chkp%payloads(i)%ptr%name) .eq. trim(name)) then
1116 payload => chkp%payloads(i)%ptr
1117 return
1118 end if
1119 end do
1120
1121 end function chkp_find_payload
1122
1125 subroutine chkp_file_set_overwrite(this, overwrite)
1126 class(chkp_file_t), intent(inout) :: this
1127 logical, intent(in) :: overwrite
1128 this%overwrite = overwrite
1129 end subroutine chkp_file_set_overwrite
1130end module chkp_file
Format-independent checkpoint payloads.
Defines format-independent checkpoint registration and restart state.
Neko legacy checkpoint file format.
Definition chkp_file.f90:36
subroutine chkp_file_write(this, data, t)
Write a Neko legacy checkpoint.
subroutine chkp_file_read(this, data)
Load a Neko legacy checkpoint.
character(len=1024) function chkp_file_get_next_output_fname(this)
Get the physical file name generated by the next write.
type(checkpoint_payload_t) function, pointer chkp_find_payload(chkp, name)
Find a payload without making its absence an error.
subroutine chkp_file_set_overwrite(this, overwrite)
Set whether checkpoint files may be overwritten.
subroutine chkp_read_field(this, fh, byte_offset, x, nel)
Read and optionally interpolate one legacy checkpoint field.
subroutine chkp_build_legacy_view(chkp, view)
Build the fixed legacy view from format-independent payloads.
Definition comm.F90:1
type(mpi_datatype), public mpi_real_precision
MPI type for working precision of REAL types.
Definition comm.F90:54
integer, public pe_rank
MPI rank.
Definition comm.F90:59
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Contains the field_serties_t type.
Defines a field.
Definition field.f90:34
Implements global_interpolation given a dofmap.
Routines to interpolate between different spaces.
Logging routines.
Definition log.f90:34
integer, parameter, public neko_log_verbose
Verbose.
Definition log.f90:54
type(log_t), public neko_log
Global log stream.
Definition log.f90:91
Definition math.f90:60
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:239
Defines a mesh.
Definition mesh.f90:34
MPI derived types.
Definition mpi_types.f90:34
integer, public mpi_double_precision_size
Size of MPI type double precision.
Definition mpi_types.f90:66
integer, public mpi_real_prec_size
Size of working precision REAL types.
Definition mpi_types.f90:70
integer, public mpi_integer_size
Size of MPI type integer.
Definition mpi_types.f90:68
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
integer, parameter, public gll
Definition space.f90:50
Utilities.
Definition utils.f90:35
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Definition utils.f90:111
Collection of live simulation data registered for checkpointing.
A named real array and its selection in a global checkpoint dataset.
A named nodal real array distributed over mesh elements.
A named collection of live fields to checkpoint together.
Interface for Neko legacy checkpoint files.
Definition chkp_file.f90:95
Temporary view of the payloads required by the positional .chkp format.
Definition chkp_file.f90:64
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
A generic file handler.
Implements global interpolation for arbitrary points in the domain.
Interpolation between two space::space_t.
The function space for the SEM solution fields.
Definition space.f90:64