50#ifdef HAVE_ADIOS2_FORTRAN
52 use mpi_f08,
only : mpi_bcast, mpi_character, mpi_integer
64#ifdef HAVE_ADIOS2_FORTRAN
65 type(adios2_adios) :: adios
66 type(adios2_io) :: iowriter
67 type(adios2_io) :: ioreader
72 logical :: dp_precision = .false.
87 character(len=1024) :: fname
90 counter = this%get_counter()
91 if (counter .eq. -1)
then
92 counter = this%get_start_counter()
104 integer,
intent(in) :: counter
105 character(len=1024) :: fname
106 character(len=1024) :: base_fname
107 character(len=8) :: id_str
108 integer :: suffix_pos
110 base_fname = this%get_base_fname()
112 write(id_str,
'(i5.5,a)') counter,
'.bp'
113 fname = trim(base_fname(1:suffix_pos-1)) //
"0." // id_str
117#ifdef HAVE_ADIOS2_FORTRAN
121 class(*),
target,
intent(in) :: data
122 real(kind=
rp),
intent(in),
optional :: t
124 type(
mesh_t),
pointer :: msh
127 real(kind=
dp) :: time
128 character(len=132) :: hdr
129 character :: rdcode(10)
130 character(len=8) :: id_str
131 character(len=1024) :: fname, base_fname
132 character(len=1024) :: start_field
133 integer :: i, j, ierr, n, suffix_pos, tslash_pos
134 integer :: lx, ly, lz, lxyz, gdim, glb_nelv, nelv, offset_el
136 integer,
allocatable :: idx(:)
138 integer :: n_scalar_fields
139 logical :: write_mesh, write_velocity, write_pressure, write_temperature
140 integer :: adios2_type
141 type(adios2_engine) :: bpwriter
142 type(adios2_variable) :: variable_idx, variable_hdr, variable, variable_msh
143 type(adios2_variable) :: variable_v, variable_p, variable_temp
144 integer(kind=8),
dimension(1) :: shape_dims, start_dims, count_dims
157 write_velocity = .false.
158 write_pressure = .false.
159 write_temperature = .false.
165 if (data%x%size() .gt. 0) x%ptr => data%x%x
166 if (data%y%size() .gt. 0) y%ptr => data%y%x
167 if (data%z%size() .gt. 0) z%ptr => data%z%x
168 if (data%u%size() .gt. 0)
then
170 write_velocity = .true.
172 if (data%v%size() .gt. 0) v%ptr => data%v%x
173 if (data%w%size() .gt. 0) w%ptr => data%w%x
174 if (data%p%size() .gt. 0)
then
176 write_pressure = .true.
178 if (data%t%size() .gt. 0)
then
179 write_temperature = .true.
182 n_scalar_fields = data%n_scalars
183 allocate(scalar_fields(n_scalar_fields))
184 do i = 1, n_scalar_fields
185 scalar_fields(i)%ptr => data%s(i)%x
192 glb_nelv = data%glb_nelv
193 offset_el = data%offset_el
201 select case (data%size())
203 p%ptr => data%items(1)%ptr%x(:,1,1,1)
204 write_pressure = .true.
206 p%ptr => data%items(1)%ptr%x(:,1,1,1)
207 tem%ptr => data%items(2)%ptr%x(:,1,1,1)
208 write_pressure = .true.
209 write_temperature = .true.
211 u%ptr => data%items(1)%ptr%x(:,1,1,1)
212 v%ptr => data%items(2)%ptr%x(:,1,1,1)
213 w%ptr => data%items(3)%ptr%x(:,1,1,1)
214 write_velocity = .true.
216 p%ptr => data%items(1)%ptr%x(:,1,1,1)
217 u%ptr => data%items(2)%ptr%x(:,1,1,1)
218 v%ptr => data%items(3)%ptr%x(:,1,1,1)
219 w%ptr => data%items(4)%ptr%x(:,1,1,1)
220 write_pressure = .true.
221 write_velocity = .true.
223 p%ptr => data%items(1)%ptr%x(:,1,1,1)
224 u%ptr => data%items(2)%ptr%x(:,1,1,1)
225 v%ptr => data%items(3)%ptr%x(:,1,1,1)
226 w%ptr => data%items(4)%ptr%x(:,1,1,1)
228 if (trim(data%name(5)) .eq.
'temperature')
then
230 tem%ptr => data%items(5)%ptr%x(:,1,1,1)
231 n_scalar_fields = data%size() - 5
232 allocate(scalar_fields(n_scalar_fields))
233 do i = 1, n_scalar_fields
234 scalar_fields(i)%ptr => data%items(i+5)%ptr%x(:,1,1,1)
236 write_temperature = .true.
239 n_scalar_fields = data%size() - 4
240 allocate(scalar_fields(n_scalar_fields))
241 do i = 1, n_scalar_fields
242 scalar_fields(i)%ptr => data%items(i+4)%ptr%x(:,1,1,1)
244 write_temperature = .false.
246 write_pressure = .true.
247 write_velocity = .true.
249 call neko_error(
'This many fields not supported yet, bp_file')
257 if (
associated(dof))
then
258 x%ptr => dof%x(:,1,1,1)
259 y%ptr => dof%y(:,1,1,1)
260 z%ptr => dof%z(:,1,1,1)
265 if (
associated(msh))
then
267 glb_nelv = msh%glb_nelv
268 offset_el = msh%offset_el
271 allocate(idx(msh%nelv))
273 idx(i) = msh%elements(i)%e%id()
277 if (
associated(xh))
then
286 if (this%dp_precision)
then
287 adios2_type = adios2_type_dp
289 adios2_type = adios2_type_real
293 call outbuf_points%init(this%dp_precision, gdim, glb_nelv, offset_el, &
296 write(*,*)
"writing layout ", this%layout
298 if (this%layout .eq. 1)
then
300 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
302 else if (this%layout .eq. 2)
then
304 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
306 else if (this%layout .eq. 4)
then
319 call this%increment_counter()
320 write_mesh = (this%get_counter() .eq. this%get_start_counter())
330 if (write_velocity)
then
334 if (write_pressure)
then
338 if (write_temperature)
then
342 if (n_scalar_fields .gt. 0 )
then
345 write(rdcode(i),
'(i1)') (n_scalar_fields)/10
347 write(rdcode(i),
'(i1)') (n_scalar_fields) - 10*((n_scalar_fields)/10)
352 write(hdr, 1) adios2_type, lx, ly, lz, this%layout, glb_nelv, &
353 time, this%get_counter(),
npar, (rdcode(i), i = 1, 10)
3541
format(
'#std',1x, i1, 1x,
i2, 1x,
i2, 1x,
i2, 1x, i10, 1x, i10, 1x, &
355 e20.13, 1x, i9, 1x, i6, 1x, 10a)
359 base_fname = this%get_base_fname()
363 if (.not. adios%valid)
then
365 call adios2_init(adios,
'adios2.xml',
neko_comm%mpi_val, ierr)
368 if (.not. iowriter%valid)
then
369 call adios2_declare_io(iowriter, adios,
'writer', ierr)
370 call adios2_set_engine(iowriter,
'BP5', ierr)
373 call adios2_open(bpwriter, iowriter, trim(fname), adios2_mode_write, &
375 call adios2_begin_step(bpwriter, ierr)
378 call adios2_inquire_variable(variable_hdr, iowriter,
'header', ierr)
379 if (.not.variable_hdr%valid)
then
380 call adios2_define_variable(variable_hdr, iowriter,
'header', &
381 adios2_type_character, ierr)
383 call adios2_put(bpwriter, variable_hdr, hdr, adios2_mode_sync, ierr)
386 shape_dims = (int(glb_nelv,
i8))
387 start_dims = (int(offset_el,
i8))
388 count_dims = (int(nelv,
i8))
389 call adios2_inquire_variable(variable_idx, iowriter,
'idx', ierr)
390 if (.not.variable_idx%valid)
then
391 call adios2_define_variable(variable_idx, iowriter,
'idx', &
392 adios2_type_integer4,
size(shape_dims), shape_dims, start_dims, &
393 count_dims, .false., ierr)
395 call adios2_set_shape(variable_idx,
size(shape_dims), shape_dims, ierr)
396 call adios2_set_selection(variable_idx,
size(start_dims), &
397 start_dims, count_dims, ierr)
399 call adios2_put(bpwriter, variable_idx, idx, adios2_mode_sync, ierr)
405 call outbuf_points%define(variable, iowriter,
'points-x', ierr)
408 call outbuf_points%define(variable, iowriter,
'points-y', ierr)
411 call outbuf_points%define(variable, iowriter,
'points-z', ierr)
415 if (write_velocity)
then
417 if (this%layout .le. 3)
then
418 call outbuf_npar%define(variable, iowriter,
'velocity-u', ierr)
422 if (this%layout .le. 3)
then
423 call outbuf_npar%define(variable, iowriter,
'velocity-v', ierr)
427 if (this%layout .le. 3)
then
428 call outbuf_npar%define(variable, iowriter,
'velocity-w', ierr)
433 if (write_pressure)
then
435 if (this%layout .le. 3)
then
436 call outbuf_npar%define(variable, iowriter,
'pressure', ierr)
441 if (write_temperature)
then
443 if (this%layout .le. 3)
then
444 call outbuf_npar%define(variable, iowriter,
'temperature', ierr)
449 do i = 1, n_scalar_fields
451 if (this%layout .le. 3)
then
452 write(id_str,
'(a,i1,i1)')
's', i / 10, i - 10*(i / 10)
453 call outbuf_npar%define(variable, iowriter, trim(id_str), ierr)
458 if (this%layout .gt. 3)
then
459 call outbuf_npar%define(variable, iowriter,
'fields', ierr)
463 call adios2_end_step(bpwriter, ierr)
464 call adios2_close(bpwriter, ierr)
469 write(start_field,
"(I5,A7)") this%get_start_counter(),
'.adios2'
470 open(newunit = file_unit, &
471 file = trim(base_fname(1:suffix_pos - 1)) &
472 // trim(adjustl(start_field)), status =
'replace')
473 write(file_unit, fmt =
'(A,A,A)')
'filetemplate: ', &
474 base_fname(tslash_pos+1:suffix_pos-1),
'%01d.%05d.bp'
475 write(file_unit, fmt =
'(A,i5)')
'firsttimestep: ', &
476 this%get_start_counter()
477 write(file_unit, fmt =
'(A,i5)')
'numtimesteps: ', &
478 (this%get_counter() + 1) - this%get_start_counter()
479 write(file_unit, fmt =
'(A)')
'type: adios2-bp'
490 class(*),
target,
intent(inout) :: data
491 character(len=132) :: hdr
492 integer :: ierr, suffix_pos, i, j
493 character(len=1024) :: fname, meta_fname, string, base_fname
494 logical :: meta_file, read_mesh, read_velocity, read_pressure
496 character(len=8) :: id_str
497 integer :: lx, ly, lz, glb_nelv, counter, lxyz
499 integer :: adios2_type, n_scalars, n
500 real(kind=
rp) :: time
502 character :: rdcode(10), temp_str(4)
503 class(
buffer_t),
allocatable :: inpbuf_points, inpbuf
504 type(adios2_engine) :: bpreader
505 type(adios2_variable) :: variable_hdr, variable_idx, variable
506 integer(kind=8),
dimension(1) :: start_dims, count_dims
511 base_fname = this%get_base_fname()
513 meta_fname = trim(base_fname(1:suffix_pos-1))
517 inquire(
file = trim(meta_fname), exist = meta_file)
518 if (meta_file .and. data%meta_nsamples .eq. 0)
then
520 open(newunit = file_unit,
file = trim(meta_fname))
521 read(file_unit, fmt =
'(A)') string
522 read(string(14:), fmt =
'(A)') string
523 string = trim(string)
524 data%fld_series_fname = string(:scan(trim(string),
'%') - 1)
525 data%fld_series_fname = trim(data%fld_series_fname) //
'0'
526 read(file_unit, fmt =
'(A)') string
527 read(string(scan(string,
':')+1:), *) data%meta_start_counter
528 read(file_unit, fmt =
'(A)') string
529 read(string(scan(string,
':')+1:), *) data%meta_nsamples
532 write(*,*)
'Reading meta file for bp series'
533 write(*,*)
'Name: ', trim(data%fld_series_fname)
534 write(*,*)
'Start counter: ', data%meta_start_counter, &
535 'Nsamples: ', data%meta_nsamples
537 call mpi_bcast(data%fld_series_fname, 1024, mpi_character, 0, &
539 call mpi_bcast(data%meta_start_counter, 1, mpi_integer, 0, &
541 call mpi_bcast(data%meta_nsamples, 1, mpi_integer, 0, &
543 if (this%get_counter() .eq. 0) &
544 call this%set_counter(data%meta_start_counter)
548 write(id_str,
'(i5.5,a)') this%get_counter(),
'.bp'
549 fname = trim(data%fld_series_fname) //
'.' // id_str
550 if (this%get_counter() .ge. data%meta_nsamples + &
551 data%meta_start_counter)
then
552 call neko_error(
'Trying to read more bp files than exist')
562 if (.not.adios%valid)
then
564 call adios2_init(adios,
'adios2.xml',
neko_comm%mpi_val, ierr)
566 if (.not.ioreader%valid)
then
567 call adios2_declare_io(ioreader, adios,
'reader', ierr)
568 call adios2_set_engine(ioreader,
'BP5', ierr)
573 call adios2_open(bpreader, ioreader, trim(fname), adios2_mode_read, &
575 call adios2_begin_step(bpreader, ierr)
578 if (.not.variable_hdr%valid)
then
579 call adios2_inquire_variable(variable_hdr, ioreader,
'header', ierr)
581 call adios2_get(bpreader, variable_hdr, hdr, adios2_mode_sync, ierr)
583 read(hdr, 1) temp_str, adios2_type, lx, ly, lz, this%layout, glb_nelv,&
584 time, counter,
npar, (rdcode(i),i = 1,10)
5851
format(4a, 1x, i1, 1x,
i2, 1x,
i2, 1x,
i2, 1x, i10, 1x, i10, 1x, &
586 e20.13, 1x, i9, 1x, i6, 1x, 10a)
587 if (data%nelv .eq. 0)
then
589 data%nelv = dist%num_local()
590 data%offset_el = dist%start_idx()
595 data%glb_nelv = glb_nelv
596 data%t_counter = counter
607 if (adios2_type .eq. adios2_type_dp)
then
608 this%dp_precision = .true.
610 this%dp_precision = .false.
613 if (.not.
allocated(inpbuf_points))
allocate(
buffer_1d_t::inpbuf_points)
614 call inpbuf_points%init(this%dp_precision, data%gdim, data%glb_nelv, &
615 data%offset_el, data%nelv, lx, ly, lz)
617 write(*,*)
"layout ", this%layout
618 if (this%layout .eq. 1)
then
619 if (.not.
allocated(inpbuf))
allocate(
buffer_1d_t::inpbuf)
620 else if (this%layout .eq. 2)
then
621 if (.not.
allocated(inpbuf))
allocate(
buffer_4d_t::inpbuf)
622 else if (this%layout .eq. 3)
then
628 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
629 data%offset_el, data%nelv, lx, ly, lz)
631 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
632 data%offset_el, data%nelv, lx, ly, lz)
634 call inpbuf%init(this%dp_precision,
npar, data%glb_nelv, &
635 data%offset_el, data%nelv, lx, ly, lz)
642 read_velocity = .false.
643 read_pressure = .false.
645 if (rdcode(i) .eq.
'X')
then
647 if (data%x%size() .ne. n)
call data%x%init(n)
648 if (data%y%size() .ne. n)
call data%y%init(n)
649 if (data%z%size() .ne. n)
call data%z%init(n)
652 if (rdcode(i) .eq.
'U')
then
653 read_velocity = .true.
654 if (data%u%size() .ne. n)
call data%u%init(n)
655 if (data%v%size() .ne. n)
call data%v%init(n)
656 if (data%w%size() .ne. n)
call data%w%init(n)
659 if (rdcode(i) .eq.
'P')
then
660 read_pressure = .true.
661 if (data%p%size() .ne. n)
call data%p%init(n)
664 if (rdcode(i) .eq.
'T')
then
666 if (data%t%size() .ne. n)
call data%t%init(n)
670 if (rdcode(i) .eq.
'S')
then
672 read(rdcode(i),*) n_scalars
673 n_scalars = n_scalars*10
676 n_scalars = n_scalars+j
678 if (
allocated(data%s))
then
679 if (data%n_scalars .ne. n_scalars)
then
680 do j = 1, data%n_scalars
681 call data%s(j)%free()
684 data%n_scalars = n_scalars
685 allocate(data%s(n_scalars))
686 do j = 1, data%n_scalars
687 call data%s(j)%init(n)
691 data%n_scalars = n_scalars
692 allocate(data%s(data%n_scalars))
693 do j = 1, data%n_scalars
694 call data%s(j)%init(n)
700 if (
allocated(data%idx))
then
701 if (
size(data%idx) .ne. data%nelv)
then
703 allocate(data%idx(data%nelv))
706 allocate(data%idx(data%nelv))
710 start_dims = (int(data%offset_el,
i8))
711 count_dims = (int(data%nelv,
i8))
712 call adios2_inquire_variable(variable_idx, ioreader,
'idx', ierr)
713 if (variable_idx%valid)
then
714 call adios2_set_selection(variable_idx,
size(start_dims), &
715 start_dims, count_dims, ierr)
717 call adios2_get(bpreader, variable_idx, data%idx, adios2_mode_sync, ierr)
720 call inpbuf_points%inquire(variable, ioreader,
'points-x', ierr)
721 call inpbuf_points%read(bpreader, variable, ierr)
722 call inpbuf_points%copy(data%x)
723 call inpbuf_points%inquire(variable, ioreader,
'points-y', ierr)
724 call inpbuf_points%read(bpreader, variable, ierr)
725 call inpbuf_points%copy(data%y)
726 call inpbuf_points%inquire(variable, ioreader,
'points-z', ierr)
727 call inpbuf_points%read(bpreader, variable, ierr)
728 call inpbuf_points%copy(data%z)
731 if (this%layout .eq. 3)
then
732 call inpbuf%inquire(variable, ioreader,
'fields', ierr)
733 call inpbuf%read(bpreader, variable, ierr)
736 if (read_velocity)
then
737 if (this%layout .le. 3)
then
738 call inpbuf%inquire(variable, ioreader,
'velocity-u', ierr)
739 call inpbuf%read(bpreader, variable, ierr)
741 call inpbuf%copy(data%u)
742 if (this%layout .le. 3)
then
743 call inpbuf%inquire(variable, ioreader,
'velocity-v', ierr)
744 call inpbuf%read(bpreader, variable, ierr)
746 call inpbuf%copy(data%v)
747 if (this%layout .le. 3)
then
748 call inpbuf%inquire(variable, ioreader,
'velocity-w', ierr)
749 call inpbuf%read(bpreader, variable, ierr)
751 call inpbuf%copy(data%w)
754 if (read_pressure)
then
755 if (this%layout .le. 3)
then
756 call inpbuf%inquire(variable, ioreader,
'pressure', ierr)
757 call inpbuf%read(bpreader, variable, ierr)
759 call inpbuf%copy(data%p)
763 if (this%layout .le. 3)
then
764 call inpbuf%inquire(variable, ioreader,
'temperature', ierr)
765 call inpbuf%read(bpreader, variable, ierr)
767 call inpbuf%copy(data%t)
771 if (this%layout .le. 3)
then
772 write(id_str,
'(a,i1,i1)')
's', i/10, i-10*(i/10)
773 call inpbuf%inquire(variable, ioreader, trim(id_str), ierr)
774 call inpbuf%read(bpreader, variable, ierr)
776 call inpbuf%copy(data%s(i))
779 call adios2_end_step(bpreader, ierr)
780 call adios2_close(bpreader, ierr)
782 call this%increment_counter()
784 if (
allocated(inpbuf_points))
deallocate(inpbuf_points)
785 if (
allocated(inpbuf))
deallocate(inpbuf)
787 call neko_error(
'Currently we only read into fld_file_data_t,&
788 please use that data structure instead.&
789 (output_format.adios2)')
798 class(*),
target,
intent(in) :: data
799 real(kind=
rp),
intent(in),
optional :: t
800 call neko_error(
'Neko needs to be built with ADIOS2 Fortran support')
805 class(*),
target,
intent(inout) :: data
806 call neko_error(
'Neko needs to be built with ADIOS2 Fortran support')
813 integer,
intent(in) :: precision
815 if (precision .eq.
dp)
then
816 this%dp_precision = .true.
817 else if (precision .eq.
sp)
then
818 this%dp_precision = .false.
827 integer,
intent(in) :: layout
830 if (layout .ge. 1 .and. layout .le. 3)
then
subroutine bp_file_read(this, data)
class(buffer_t), allocatable, private outbuf_npar
character(len=1024) function bp_file_format_fname(this, counter)
Format the physical file name for a counter value.
character(len=1024) function bp_file_get_next_output_fname(this)
Get the physical file name generated by the next write.
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.