49#ifdef HAVE_ADIOS2_FORTRAN
51 use mpi_f08,
only : mpi_bcast, mpi_character, mpi_integer
63#ifdef HAVE_ADIOS2_FORTRAN
64 type(adios2_adios) :: adios
65 type(adios2_io) :: iowriter
66 type(adios2_io) :: ioreader
71 logical :: dp_precision = .false.
82#ifdef HAVE_ADIOS2_FORTRAN
86 class(*),
target,
intent(in) :: data
87 real(kind=
rp),
intent(in),
optional :: t
89 type(
mesh_t),
pointer :: msh
93 character(len=132) :: hdr
94 character :: rdcode(10)
95 character(len=8) :: id_str
96 character(len=1024) :: fname, base_fname
97 character(len=1024) :: start_field
98 integer :: i, j, ierr, n, suffix_pos, tslash_pos
99 integer :: lx, ly, lz, lxyz, gdim, glb_nelv, nelv, offset_el
101 integer,
allocatable :: idx(:)
103 integer :: n_scalar_fields
104 logical :: write_mesh, write_velocity, write_pressure, write_temperature
105 integer :: adios2_type
106 type(adios2_engine) :: bpwriter
107 type(adios2_variable) :: variable_idx, variable_hdr, variable, variable_msh
108 type(adios2_variable) :: variable_v, variable_p, variable_temp
109 integer(kind=8),
dimension(1) :: shape_dims, start_dims, count_dims
122 write_velocity = .false.
123 write_pressure = .false.
124 write_temperature = .false.
130 if (data%x%n .gt. 0) x%ptr => data%x%x
131 if (data%y%n .gt. 0) y%ptr => data%y%x
132 if (data%z%n .gt. 0) z%ptr => data%z%x
133 if (data%u%n .gt. 0)
then
135 write_velocity = .true.
137 if (data%v%n .gt. 0) v%ptr => data%v%x
138 if (data%w%n .gt. 0) w%ptr => data%w%x
139 if (data%p%n .gt. 0)
then
141 write_pressure = .true.
143 if (data%t%n .gt. 0)
then
144 write_temperature = .true.
147 n_scalar_fields = data%n_scalars
148 allocate(scalar_fields(n_scalar_fields))
149 do i = 1, n_scalar_fields
150 scalar_fields(i)%ptr => data%s(i)%x
157 glb_nelv = data%glb_nelv
158 offset_el = data%offset_el
166 select case (data%size())
168 p%ptr => data%items(1)%ptr%x(:,1,1,1)
169 write_pressure = .true.
171 p%ptr => data%items(1)%ptr%x(:,1,1,1)
172 tem%ptr => data%items(2)%ptr%x(:,1,1,1)
173 write_pressure = .true.
174 write_temperature = .true.
176 u%ptr => data%items(1)%ptr%x(:,1,1,1)
177 v%ptr => data%items(2)%ptr%x(:,1,1,1)
178 w%ptr => data%items(3)%ptr%x(:,1,1,1)
179 write_velocity = .true.
181 p%ptr => data%items(1)%ptr%x(:,1,1,1)
182 u%ptr => data%items(2)%ptr%x(:,1,1,1)
183 v%ptr => data%items(3)%ptr%x(:,1,1,1)
184 w%ptr => data%items(4)%ptr%x(:,1,1,1)
185 write_pressure = .true.
186 write_velocity = .true.
188 p%ptr => data%items(1)%ptr%x(:,1,1,1)
189 u%ptr => data%items(2)%ptr%x(:,1,1,1)
190 v%ptr => data%items(3)%ptr%x(:,1,1,1)
191 w%ptr => data%items(4)%ptr%x(:,1,1,1)
193 if (trim(data%name(5)) .eq.
'temperature')
then
195 tem%ptr => data%items(5)%ptr%x(:,1,1,1)
196 n_scalar_fields = data%size() - 5
197 allocate(scalar_fields(n_scalar_fields))
198 do i = 1, n_scalar_fields
199 scalar_fields(i)%ptr => data%items(i+5)%ptr%x(:,1,1,1)
201 write_temperature = .true.
204 n_scalar_fields = data%size() - 4
205 allocate(scalar_fields(n_scalar_fields))
206 do i = 1, n_scalar_fields
207 scalar_fields(i)%ptr => data%items(i+4)%ptr%x(:,1,1,1)
209 write_temperature = .false.
211 write_pressure = .true.
212 write_velocity = .true.
214 call neko_error(
'This many fields not supported yet, bp_file')
222 if (
associated(dof))
then
223 x%ptr => dof%x(:,1,1,1)
224 y%ptr => dof%y(:,1,1,1)
225 z%ptr => dof%z(:,1,1,1)
230 if (
associated(msh))
then
232 glb_nelv = msh%glb_nelv
233 offset_el = msh%offset_el
236 allocate(idx(msh%nelv))
238 idx(i) = msh%elements(i)%e%id()
242 if (
associated(xh))
then
251 if (this%dp_precision)
then
252 adios2_type = adios2_type_dp
254 adios2_type = adios2_type_real
258 call outbuf_points%init(this%dp_precision, gdim, glb_nelv, offset_el, &
261 write(*,*)
"writing layout ", this%layout
263 if (this%layout .eq. 1)
then
265 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
267 else if (this%layout .eq. 2)
then
269 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
271 else if (this%layout .eq. 4)
then
284 write_mesh = (this%counter .eq. this%start_counter)
294 if (write_velocity)
then
298 if (write_pressure)
then
302 if (write_temperature)
then
306 if (n_scalar_fields .gt. 0 )
then
309 write(rdcode(i),
'(i1)') (n_scalar_fields)/10
311 write(rdcode(i),
'(i1)') (n_scalar_fields) - 10*((n_scalar_fields)/10)
316 write(hdr, 1) adios2_type, lx, ly, lz, this%layout, glb_nelv, &
317 time, this%counter,
npar, (rdcode(i), i = 1, 10)
3181
format(
'#std',1x, i1, 1x,
i2, 1x,
i2, 1x,
i2, 1x, i10, 1x, i10, 1x, &
319 e20.13, 1x, i9, 1x, i6, 1x, 10a)
324 base_fname = this%get_base_fname()
326 write(id_str,
'(i5.5,a)') this%counter,
'.bp'
327 fname = trim(base_fname(1:suffix_pos-1)) //
"0." // id_str
329 if (.not. adios%valid)
then
331 call adios2_init(adios,
'adios2.xml',
neko_comm%mpi_val, ierr)
334 if (.not. iowriter%valid)
then
335 call adios2_declare_io(iowriter, adios,
'writer', ierr)
336 call adios2_set_engine(iowriter,
'BP5', ierr)
339 call adios2_open(bpwriter, iowriter, trim(fname), adios2_mode_write, &
341 call adios2_begin_step(bpwriter, ierr)
344 call adios2_inquire_variable(variable_hdr, iowriter,
'header', ierr)
345 if (.not.variable_hdr%valid)
then
346 call adios2_define_variable(variable_hdr, iowriter,
'header', &
347 adios2_type_character, ierr)
349 call adios2_put(bpwriter, variable_hdr, hdr, adios2_mode_sync, ierr)
352 shape_dims = (int(glb_nelv,
i8))
353 start_dims = (int(offset_el,
i8))
354 count_dims = (int(nelv,
i8))
355 call adios2_inquire_variable(variable_idx, iowriter,
'idx', ierr)
356 if (.not.variable_idx%valid)
then
357 call adios2_define_variable(variable_idx, iowriter,
'idx', &
358 adios2_type_integer4,
size(shape_dims), shape_dims, start_dims, &
359 count_dims, .false., ierr)
361 call adios2_set_shape(variable_idx,
size(shape_dims), shape_dims, ierr)
362 call adios2_set_selection(variable_idx,
size(start_dims), &
363 start_dims, count_dims, ierr)
365 call adios2_put(bpwriter, variable_idx, idx, adios2_mode_sync, ierr)
371 call outbuf_points%define(variable, iowriter,
'points-x', ierr)
374 call outbuf_points%define(variable, iowriter,
'points-y', ierr)
377 call outbuf_points%define(variable, iowriter,
'points-z', ierr)
381 if (write_velocity)
then
383 if (this%layout .le. 3)
then
384 call outbuf_npar%define(variable, iowriter,
'velocity-u', ierr)
388 if (this%layout .le. 3)
then
389 call outbuf_npar%define(variable, iowriter,
'velocity-v', ierr)
393 if (this%layout .le. 3)
then
394 call outbuf_npar%define(variable, iowriter,
'velocity-w', ierr)
399 if (write_pressure)
then
401 if (this%layout .le. 3)
then
402 call outbuf_npar%define(variable, iowriter,
'pressure', ierr)
407 if (write_temperature)
then
409 if (this%layout .le. 3)
then
410 call outbuf_npar%define(variable, iowriter,
'temperature', ierr)
415 do i = 1, n_scalar_fields
417 if (this%layout .le. 3)
then
418 write(id_str,
'(a,i1,i1)')
's', i / 10, i - 10*(i / 10)
419 call outbuf_npar%define(variable, iowriter, trim(id_str), ierr)
424 if (this%layout .gt. 3)
then
425 call outbuf_npar%define(variable, iowriter,
'fields', ierr)
429 call adios2_end_step(bpwriter, ierr)
430 call adios2_close(bpwriter, ierr)
435 write(start_field,
"(I5,A7)") this%start_counter,
'.adios2'
436 open(unit = newunit(file_unit), &
437 file = trim(base_fname(1:suffix_pos - 1)) &
438 // trim(adjustl(start_field)), status=
'replace')
439 write(file_unit, fmt =
'(A,A,A)')
'filetemplate: ', &
440 base_fname(tslash_pos+1:suffix_pos-1),
'%01d.%05d.bp'
441 write(file_unit, fmt =
'(A,i5)')
'firsttimestep: ', this%start_counter
442 write(file_unit, fmt =
'(A,i5)')
'numtimesteps: ', &
443 (this%counter + 1) - this%start_counter
444 write(file_unit, fmt =
'(A)')
'type: adios2-bp'
448 this%counter = this%counter + 1
457 class(*),
target,
intent(inout) :: data
458 character(len=132) :: hdr
459 integer :: ierr, suffix_pos, i, j
460 character(len=1024) :: fname, meta_fname, string, base_fname
461 logical :: meta_file, read_mesh, read_velocity, read_pressure
463 character(len=8) :: id_str
464 integer :: lx, ly, lz, glb_nelv, counter, lxyz
466 integer :: adios2_type, n_scalars, n
467 real(kind=
rp) :: time
469 character :: rdcode(10), temp_str(4)
470 class(
buffer_t),
allocatable :: inpbuf_points, inpbuf
471 type(adios2_engine) :: bpreader
472 type(adios2_variable) :: variable_hdr, variable_idx, variable
473 integer(kind=8),
dimension(1) :: start_dims, count_dims
478 base_fname = this%get_base_fname()
480 meta_fname = trim(base_fname(1:suffix_pos-1))
484 inquire(
file = trim(meta_fname), exist = meta_file)
485 if (meta_file .and. data%meta_nsamples .eq. 0)
then
487 open(unit = newunit(file_unit),
file = trim(meta_fname))
488 read(file_unit, fmt =
'(A)') string
489 read(string(14:), fmt =
'(A)') string
490 string = trim(string)
491 data%fld_series_fname = string(:scan(trim(string),
'%') - 1)
492 data%fld_series_fname = trim(data%fld_series_fname) //
'0'
493 read(file_unit, fmt =
'(A)') string
494 read(string(scan(string,
':')+1:), *) data%meta_start_counter
495 read(file_unit, fmt =
'(A)') string
496 read(string(scan(string,
':')+1:), *) data%meta_nsamples
499 write(*,*)
'Reading meta file for bp series'
500 write(*,*)
'Name: ', trim(data%fld_series_fname)
501 write(*,*)
'Start counter: ', data%meta_start_counter, &
502 'Nsamples: ', data%meta_nsamples
504 call mpi_bcast(data%fld_series_fname, 1024, mpi_character, 0, &
506 call mpi_bcast(data%meta_start_counter, 1, mpi_integer, 0, &
508 call mpi_bcast(data%meta_nsamples, 1, mpi_integer, 0, &
510 if (this%counter .eq. 0) this%counter = data%meta_start_counter
514 write(id_str,
'(i5.5,a)') this%counter,
'.bp'
515 fname = trim(data%fld_series_fname) //
'.' // id_str
516 if (this%counter .ge. data%meta_nsamples+data%meta_start_counter)
then
517 call neko_error(
'Trying to read more bp files than exist')
527 if (.not.adios%valid)
then
529 call adios2_init(adios,
'adios2.xml',
neko_comm%mpi_val, ierr)
531 if (.not.ioreader%valid)
then
532 call adios2_declare_io(ioreader, adios,
'reader', ierr)
533 call adios2_set_engine(ioreader,
'BP5', ierr)
538 call adios2_open(bpreader, ioreader, trim(fname), adios2_mode_read, &
540 call adios2_begin_step(bpreader, ierr)
543 if (.not.variable_hdr%valid)
then
544 call adios2_inquire_variable(variable_hdr, ioreader,
'header', ierr)
546 call adios2_get(bpreader, variable_hdr, hdr, adios2_mode_sync, ierr)
548 read(hdr, 1) temp_str, adios2_type, lx, ly, lz, this%layout, glb_nelv,&
549 time, counter,
npar, (rdcode(i),i = 1,10)
5501
format(4a, 1x, i1, 1x,
i2, 1x,
i2, 1x,
i2, 1x, i10, 1x, i10, 1x, &
551 e20.13, 1x, i9, 1x, i6, 1x, 10a)
552 if (data%nelv .eq. 0)
then
554 data%nelv = dist%num_local()
555 data%offset_el = dist%start_idx()
560 data%glb_nelv = glb_nelv
561 data%t_counter = counter
572 if (adios2_type .eq. adios2_type_dp)
then
573 this%dp_precision = .true.
575 this%dp_precision = .false.
578 if (.not.
allocated(inpbuf_points))
allocate(
buffer_1d_t::inpbuf_points)
579 call inpbuf_points%init(this%dp_precision, data%gdim, data%glb_nelv, &
580 data%offset_el, data%nelv, lx, ly, lz)
582 write(*,*)
"layout ", this%layout
583 if (this%layout .eq. 1)
then
584 if (.not.
allocated(inpbuf))
allocate(
buffer_1d_t::inpbuf)
585 else if (this%layout .eq. 2)
then
586 if (.not.
allocated(inpbuf))
allocate(
buffer_4d_t::inpbuf)
587 else if (this%layout .eq. 3)
then
593 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
594 data%offset_el, data%nelv, lx, ly, lz)
596 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
597 data%offset_el, data%nelv, lx, ly, lz)
599 call inpbuf%init(this%dp_precision,
npar, data%glb_nelv, &
600 data%offset_el, data%nelv, lx, ly, lz)
607 read_velocity = .false.
608 read_pressure = .false.
610 if (rdcode(i) .eq.
'X')
then
612 if (data%x%n .ne. n)
call data%x%init(n)
613 if (data%y%n .ne. n)
call data%y%init(n)
614 if (data%z%n .ne. n)
call data%z%init(n)
617 if (rdcode(i) .eq.
'U')
then
618 read_velocity = .true.
619 if (data%u%n .ne. n)
call data%u%init(n)
620 if (data%v%n .ne. n)
call data%v%init(n)
621 if (data%w%n .ne. n)
call data%w%init(n)
624 if (rdcode(i) .eq.
'P')
then
625 read_pressure = .true.
626 if (data%p%n .ne. n)
call data%p%init(n)
629 if (rdcode(i) .eq.
'T')
then
631 if (data%t%n .ne. n)
call data%t%init(n)
635 if (rdcode(i) .eq.
'S')
then
637 read(rdcode(i),*) n_scalars
638 n_scalars = n_scalars*10
641 n_scalars = n_scalars+j
643 if (
allocated(data%s))
then
644 if (data%n_scalars .ne. n_scalars)
then
645 do j = 1, data%n_scalars
646 call data%s(j)%free()
649 data%n_scalars = n_scalars
650 allocate(data%s(n_scalars))
651 do j = 1, data%n_scalars
652 call data%s(j)%init(n)
656 data%n_scalars = n_scalars
657 allocate(data%s(data%n_scalars))
658 do j = 1, data%n_scalars
659 call data%s(j)%init(n)
665 if (
allocated(data%idx))
then
666 if (
size(data%idx) .ne. data%nelv)
then
668 allocate(data%idx(data%nelv))
671 allocate(data%idx(data%nelv))
675 start_dims = (int(data%offset_el,
i8))
676 count_dims = (int(data%nelv,
i8))
677 call adios2_inquire_variable(variable_idx, ioreader,
'idx', ierr)
678 if (variable_idx%valid)
then
679 call adios2_set_selection(variable_idx,
size(start_dims), &
680 start_dims, count_dims, ierr)
682 call adios2_get(bpreader, variable_idx, data%idx, adios2_mode_sync, ierr)
685 call inpbuf_points%inquire(variable, ioreader,
'points-x', ierr)
686 call inpbuf_points%read(bpreader, variable, ierr)
687 call inpbuf_points%copy(data%x)
688 call inpbuf_points%inquire(variable, ioreader,
'points-y', ierr)
689 call inpbuf_points%read(bpreader, variable, ierr)
690 call inpbuf_points%copy(data%y)
691 call inpbuf_points%inquire(variable, ioreader,
'points-z', ierr)
692 call inpbuf_points%read(bpreader, variable, ierr)
693 call inpbuf_points%copy(data%z)
696 if (this%layout .eq. 3)
then
697 call inpbuf%inquire(variable, ioreader,
'fields', ierr)
698 call inpbuf%read(bpreader, variable, ierr)
701 if (read_velocity)
then
702 if (this%layout .le. 3)
then
703 call inpbuf%inquire(variable, ioreader,
'velocity-u', ierr)
704 call inpbuf%read(bpreader, variable, ierr)
706 call inpbuf%copy(data%u)
707 if (this%layout .le. 3)
then
708 call inpbuf%inquire(variable, ioreader,
'velocity-v', ierr)
709 call inpbuf%read(bpreader, variable, ierr)
711 call inpbuf%copy(data%v)
712 if (this%layout .le. 3)
then
713 call inpbuf%inquire(variable, ioreader,
'velocity-w', ierr)
714 call inpbuf%read(bpreader, variable, ierr)
716 call inpbuf%copy(data%w)
719 if (read_pressure)
then
720 if (this%layout .le. 3)
then
721 call inpbuf%inquire(variable, ioreader,
'pressure', ierr)
722 call inpbuf%read(bpreader, variable, ierr)
724 call inpbuf%copy(data%p)
728 if (this%layout .le. 3)
then
729 call inpbuf%inquire(variable, ioreader,
'temperature', ierr)
730 call inpbuf%read(bpreader, variable, ierr)
732 call inpbuf%copy(data%t)
736 if (this%layout .le. 3)
then
737 write(id_str,
'(a,i1,i1)')
's', i/10, i-10*(i/10)
738 call inpbuf%inquire(variable, ioreader, trim(id_str), ierr)
739 call inpbuf%read(bpreader, variable, ierr)
741 call inpbuf%copy(data%s(i))
744 call adios2_end_step(bpreader, ierr)
745 call adios2_close(bpreader, ierr)
747 this%counter = this%counter + 1
749 if (
allocated(inpbuf_points))
deallocate(inpbuf_points)
750 if (
allocated(inpbuf))
deallocate(inpbuf)
752 call neko_error(
'Currently we only read into fld_file_data_t,&
753 please use that data structure instead.&
754 (output_format.adios2)')
763 class(*),
target,
intent(in) :: data
764 real(kind=
rp),
intent(in),
optional :: t
765 call neko_error(
'Neko needs to be built with ADIOS2 Fortran support')
770 class(*),
target,
intent(inout) :: data
771 call neko_error(
'Neko needs to be built with ADIOS2 Fortran support')
778 integer,
intent(in) :: precision
780 if (precision .eq.
dp)
then
781 this%dp_precision = .true.
782 else if (precision .eq.
sp)
then
783 this%dp_precision = .false.
792 integer,
intent(in) :: layout
795 if (layout .ge. 1 .and. layout .le. 3)
then
subroutine bp_file_read(this, data)
class(buffer_t), allocatable, private outbuf_npar
class(buffer_t), allocatable, private outbuf_points
subroutine bp_file_write(this, data, t)
subroutine bp_file_set_layout(this, layout)
subroutine bp_file_set_precision(this, precision)
Generic buffer that is extended with buffers of varying rank.
Generic buffer that is extended with buffers of varying rank.
Generic buffer that is extended with buffers of varying rank.
Generic buffer that is extended with buffers of varying rank.
integer, public pe_size
MPI size of communicator.
integer, public pe_rank
MPI rank.
type(mpi_comm), public neko_comm
MPI communicator.
Defines practical data distributions.
Defines a mapping of the degrees of freedom.
Module for file I/O operations.
Simple module to handle fld file series. Provides an interface to the different fields sotred in a fl...
integer, parameter, public i2
integer, parameter, public i8
integer, parameter, public dp
integer, parameter, public sp
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
Defines structs that are used... Dont know if we should keep it though.
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Interface for ADIOS2 bp files.
Load-balanced linear distribution .
field_list_t, To be able to group fields together
The function space for the SEM solution fields.