57 real(kind=dp),
private,
allocatable ::
tmp_dp(:)
58 real(kind=sp),
private,
allocatable ::
tmp_sp(:)
62 logical :: dp_precision = .false.
76 class(*),
target,
intent(in) :: data
77 real(kind=rp),
intent(in),
optional :: t
79 type(
mesh_t),
pointer :: msh
83 character(len=132) :: hdr
84 character :: rdcode(10)
85 character(len=6) :: id_str
86 character(len=1024) :: fname
87 character(len=1024) :: start_field
88 integer :: i, ierr, n, j,k,l,el, suffix_pos,tslash_pos
89 integer :: lx, ly, lz, lxyz, gdim, glb_nelv, nelv, offset_el
90 integer,
allocatable :: idx(:)
91 type(mpi_status) :: status
93 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset, temp_offset
94 real(kind=sp),
parameter :: test_pattern = 6.54321
96 logical :: write_mesh, write_velocity, write_pressure, write_temperature
97 integer :: fld_data_size, n_scalar_fields
109 write_pressure = .false.
110 write_velocity = .false.
111 write_temperature = .false.
115 if (data%x%n .gt. 0) x%x => data%x%x
116 if (data%y%n .gt. 0) y%x => data%y%x
117 if (data%z%n .gt. 0) z%x => data%z%x
118 if (data%u%n .gt. 0)
then
120 write_velocity = .true.
122 if (data%v%n .gt. 0) v%x => data%v%x
123 if (data%w%n .gt. 0) w%x => data%w%x
124 if (data%p%n .gt. 0)
then
126 write_pressure = .true.
128 if (data%t%n .gt. 0)
then
129 write_temperature = .true.
132 n_scalar_fields = data%n_scalars
133 allocate(scalar_fields(n_scalar_fields))
134 do i = 1, n_scalar_fields
135 scalar_fields(i)%x => data%s(i)%x
142 glb_nelv = data%glb_nelv
143 offset_el = data%offset_el
150 p%x => data%x(:,1,1,1)
152 write_pressure = .true.
153 write_velocity = .false.
155 select case (
size(data%fields))
157 p%x => data%fields(1)%f%x(:,1,1,1)
158 write_pressure = .true.
159 write_velocity = .false.
161 p%x => data%fields(1)%f%x(:,1,1,1)
162 tem%x => data%fields(2)%f%x(:,1,1,1)
163 write_pressure = .true.
164 write_temperature = .true.
166 u%x => data%fields(1)%f%x(:,1,1,1)
167 v%x => data%fields(2)%f%x(:,1,1,1)
168 w%x => data%fields(3)%f%x(:,1,1,1)
169 write_velocity = .true.
171 p%x => data%fields(1)%f%x(:,1,1,1)
172 u%x => data%fields(2)%f%x(:,1,1,1)
173 v%x => data%fields(3)%f%x(:,1,1,1)
174 w%x => data%fields(4)%f%x(:,1,1,1)
175 write_pressure = .true.
176 write_velocity = .true.
178 p%x => data%fields(1)%f%x(:,1,1,1)
179 u%x => data%fields(2)%f%x(:,1,1,1)
180 v%x => data%fields(3)%f%x(:,1,1,1)
181 w%x => data%fields(4)%f%x(:,1,1,1)
182 tem%x => data%fields(5)%f%x(:,1,1,1)
183 n_scalar_fields =
size(data%fields) - 5
184 allocate(scalar_fields(n_scalar_fields))
185 do i = 1,n_scalar_fields
186 scalar_fields(i)%x => data%fields(i+5)%f%x(:,1,1,1)
188 write_pressure = .true.
189 write_velocity = .true.
190 write_temperature = .true.
192 call neko_error(
'This many fields not supported yet, fld_file')
194 dof => data%fields(1)%f%dof
197 u%x => data%u%mf%x(:,1,1,1)
198 v%x => data%v%mf%x(:,1,1,1)
199 w%x => data%w%mf%x(:,1,1,1)
200 p%x => data%p%mf%x(:,1,1,1)
202 write_pressure = .true.
203 write_velocity = .true.
205 u%x => data%uu%mf%x(:,1,1,1)
206 v%x => data%vv%mf%x(:,1,1,1)
207 w%x => data%ww%mf%x(:,1,1,1)
208 p%x => data%pp%mf%x(:,1,1,1)
209 dof => data%pp%mf%dof
210 write_pressure = .true.
211 write_velocity = .true.
216 if (
associated(dof))
then
217 x%x => dof%x(:,1,1,1)
218 y%x => dof%y(:,1,1,1)
219 z%x => dof%z(:,1,1,1)
224 if (
associated(msh))
then
226 glb_nelv = msh%glb_nelv
227 offset_el = msh%offset_el
230 allocate(idx(msh%nelv))
232 idx(i) = msh%elements(i)%e%id()
236 if (
associated(xh))
then
245 if (this%dp_precision)
then
251 if (this%dp_precision)
then
262 write_mesh = (this%counter .eq. this%start_counter)
272 if (write_velocity)
then
276 if (write_pressure)
then
280 if (write_temperature)
then
284 if (n_scalar_fields .gt. 0 )
then
287 write(rdcode(i),
'(i1)') (n_scalar_fields)/10
289 write(rdcode(i),
'(i1)') (n_scalar_fields) - 10*((n_scalar_fields)/10)
294 write(hdr, 1) fld_data_size, lx, ly, lz,glb_nelv,glb_nelv,&
295 time, this%counter, 1, 1, (rdcode(i),i=1,10)
296 1
format(
'#std',1x,i1,1x,i2,1x,i2,1x,i2,1x,i10,1x,i10,1x,e20.13,&
297 1x,i9,1x,i6,1x,i6,1x,10a)
301 write(id_str,
'(a,i5.5)')
'f', this%counter
302 fname = trim(this%fname(1:suffix_pos-1))//
'0.'//id_str
304 call mpi_file_open(
neko_comm, trim(fname), &
305 mpi_mode_wronly + mpi_mode_create, mpi_info_null, fh, ierr)
307 call mpi_file_write_all(fh, hdr, 132, mpi_character, status, ierr)
310 call mpi_file_write_all(fh, test_pattern, 1, mpi_real, status, ierr)
313 byte_offset = mpi_offset + &
315 call mpi_file_write_at_all(fh, byte_offset, idx, nelv, &
316 mpi_integer, status, ierr)
323 byte_offset = mpi_offset + int(offset_el, i8) * &
324 (int(gdim*lxyz, i8) * &
325 int(fld_data_size, i8))
328 mpi_offset = mpi_offset + int(glb_nelv, i8) * &
329 (int(gdim *lxyz, i8) * &
330 int(fld_data_size, i8))
333 if (write_velocity)
then
334 byte_offset = mpi_offset + int(offset_el, i8) * &
335 (int(gdim * (lxyz), i8) * &
336 int(fld_data_size, i8))
339 mpi_offset = mpi_offset + int(glb_nelv, i8) * &
340 (int(gdim * (lxyz), i8) * &
341 int(fld_data_size, i8))
345 if (write_pressure)
then
346 byte_offset = mpi_offset + int(offset_el, i8) * &
348 int(fld_data_size, i8))
350 mpi_offset = mpi_offset + int(glb_nelv, i8) * &
352 int(fld_data_size, i8))
355 if (write_temperature)
then
356 byte_offset = mpi_offset + int(offset_el, i8) * &
358 int(fld_data_size, i8))
360 mpi_offset = mpi_offset + int(glb_nelv, i8) * &
362 int(fld_data_size, i8))
365 temp_offset = mpi_offset
367 do i = 1, n_scalar_fields
370 mpi_offset = int(temp_offset,i8) + int(1_i8*glb_nelv, i8) * &
372 int(fld_data_size, i8))
374 byte_offset = int(mpi_offset,i8) + int(offset_el, i8) * &
376 int(fld_data_size, i8))
378 mpi_offset = int(mpi_offset,i8) + int(glb_nelv, i8) * &
380 int(fld_data_size, i8))
387 byte_offset = int(mpi_offset,i8) + &
388 int(offset_el, i8) * &
393 mpi_offset = int(mpi_offset,i8) + &
394 int(glb_nelv, i8) * &
400 if (write_velocity)
then
401 byte_offset = int(mpi_offset,i8) + &
402 int(offset_el, i8) * &
407 mpi_offset = int(mpi_offset,i8) + &
408 int(glb_nelv, i8) * &
415 if (write_pressure)
then
416 byte_offset = int(mpi_offset,i8) + &
417 int(offset_el, i8) * &
421 mpi_offset = int(mpi_offset,i8) + &
422 int(glb_nelv, i8) * &
428 if (write_temperature)
then
429 byte_offset = int(mpi_offset,i8) + &
430 int(offset_el, i8) * &
434 mpi_offset = int(mpi_offset,i8) + &
435 int(glb_nelv, i8) * &
443 temp_offset = mpi_offset
445 do i = 1, n_scalar_fields
448 mpi_offset = int(temp_offset,i8) + &
449 int(1_i8*glb_nelv, i8) * &
454 byte_offset = int(mpi_offset,i8) + &
455 int(offset_el, i8) * &
459 mpi_offset = int(mpi_offset,i8) + &
460 int(glb_nelv, i8) * &
466 call mpi_file_sync(fh, ierr)
467 call mpi_file_close(fh, ierr)
472 write(start_field,
"(I5,A8)") this%start_counter,
'.nek5000'
473 open(unit=9,
file=trim(this%fname(1:suffix_pos-1))//trim(adjustl(start_field)), &
475 write(9, fmt=
'(A,A,A)')
'filetemplate: ', &
476 this%fname(tslash_pos+1:suffix_pos-1),
'%01d.f%05d'
477 write(9, fmt=
'(A,i5)')
'firsttimestep: ', this%start_counter
478 write(9, fmt=
'(A,i5)')
'numtimesteps: ', (this%counter + 1)-this%start_counter
479 write(9, fmt=
'(A)')
'type: binary'
483 this%counter = this%counter + 1
491 type(mpi_file),
intent(inout) :: fh
492 integer,
intent(in) :: gdim, lxyz, nelv
493 real(kind=rp),
intent(in) :: x(lxyz,nelv), y(lxyz,nelv), z(lxyz,nelv)
494 integer (kind=MPI_OFFSET_KIND),
intent(in) :: byte_offset
495 integer :: i, el, j, ierr, nout
496 type(mpi_status) :: status
497 real(kind=sp) :: buffer(2*gdim*nelv)
501 buffer(j+0) =
real(
vlmin(x(1,el),lxyz),sp)
502 buffer(j+1) =
real(
vlmax(x(1,el),lxyz),sp)
503 buffer(j+2) =
real(
vlmin(y(1,el),lxyz) ,sp)
504 buffer(j+3) =
real(
vlmax(y(1,el),lxyz),sp)
506 buffer(j+0) =
real(
vlmin(z(1,el),lxyz) ,sp)
507 buffer(j+1) =
real(
vlmax(z(1,el),lxyz),sp)
514 call mpi_file_write_at_all(fh, byte_offset, buffer, nout, &
515 mpi_real, status, ierr)
521 type(mpi_file),
intent(inout) :: fh
522 integer,
intent(in) :: lxyz, nelv
523 real(kind=rp),
intent(in) :: x(lxyz,nelv)
524 integer (kind=MPI_OFFSET_KIND),
intent(in) :: byte_offset
525 integer :: i, el, j, ierr, nout
526 type(mpi_status) :: status
527 real(kind=sp) :: buffer(2*nelv)
531 buffer(j+0) =
real(
vlmin(x(1,el),lxyz),sp)
532 buffer(j+1) =
real(
vlmax(x(1,el),lxyz),sp)
539 call mpi_file_write_at_all(fh, byte_offset, buffer, nout, &
540 mpi_real, status, ierr)
546 type(mpi_file),
intent(inout) :: fh
547 integer,
intent(inout) :: n
548 real(kind=rp),
intent(inout) :: p(n)
549 integer (kind=MPI_OFFSET_KIND),
intent(in) :: byte_offset
551 type(mpi_status) :: status
553 if ( this%dp_precision)
then
558 call mpi_file_write_at_all(fh, byte_offset,
tmp_dp, n, &
559 mpi_double_precision, status, ierr)
564 call mpi_file_write_at_all(fh, byte_offset,
tmp_sp, n, &
565 mpi_real, status, ierr)
572 type(mpi_file),
intent(inout) :: fh
573 integer,
intent(in) :: n, gdim, lxyz, nelv
574 real(kind=rp),
intent(in) :: x(lxyz,nelv), y(lxyz,nelv), z(lxyz,nelv)
575 integer (kind=MPI_OFFSET_KIND),
intent(in) :: byte_offset
576 integer :: i, el, j, ierr
577 type(mpi_status) :: status
579 if (this%dp_precision)
then
590 if (gdim .eq. 3)
then
597 call mpi_file_write_at_all(fh, byte_offset,
tmp_dp, gdim*n, &
598 mpi_double_precision, status, ierr)
610 if (gdim .eq. 3)
then
617 call mpi_file_write_at_all(fh, byte_offset,
tmp_sp, gdim*n, &
618 mpi_real, status, ierr)
627 class(*),
target,
intent(inout) :: data
628 character(len=132) :: hdr
629 integer :: ierr, suffix_pos, i, j
631 type(mpi_status) :: status
632 character(len=1024) :: fname, meta_fname, string
633 logical :: meta_file, read_mesh, read_velocity, read_pressure
635 character(len=6) :: id_str
636 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
637 integer :: lx, ly, lz, glb_nelv, counter, lxyz
638 integer :: FLD_DATA_SIZE, n_scalars, n, nd
639 real(kind=rp) :: time
640 real(kind=sp) :: temp
642 real(kind=sp),
parameter :: test_pattern = 6.54321
643 character :: rdcode(10),temp_str(4)
649 inquire(
file=trim(meta_fname), exist=meta_file)
650 if (meta_file .and. data%meta_nsamples .eq. 0)
then
652 open(unit=9,
file=trim(meta_fname))
653 read(9, fmt=
'(A)') string
654 read(string(14:),fmt=
'(A)') string
655 string = trim(string)
656 data%fld_series_fname = string(:scan(trim(string),
'%')-1)
657 data%fld_series_fname = trim(data%fld_series_fname)//
'0'
658 read(9, fmt=
'(A)') string
659 read(string(scan(string,
':')+1:),*) data%meta_start_counter
660 read(9, fmt=
'(A)') string
661 read(string(scan(string,
':')+1:),*) data%meta_nsamples
664 write(*,*)
'Reading meta file for fld series'
665 write(*,*)
'Name: ', trim(data%fld_series_fname)
666 write(*,*)
'Start counter: ', data%meta_start_counter,
'Nsamples: ', data%meta_nsamples
668 call mpi_bcast(data%fld_series_fname, 1024, mpi_character, 0,
neko_comm, ierr)
669 call mpi_bcast(data%meta_start_counter, 1, mpi_integer, 0,
neko_comm, ierr)
670 call mpi_bcast(data%meta_nsamples, 1, mpi_integer, 0,
neko_comm, ierr)
671 if(this%counter .eq. 0) this%counter = data%meta_start_counter
675 write(id_str,
'(a,i5.5)')
'f', this%counter
676 fname = trim(data%fld_series_fname)//
'.'//id_str
677 if (this%counter .ge. data%meta_nsamples+data%meta_start_counter)
then
678 call neko_error(
'Trying to read more fld files than exist')
682 write(id_str,
'(a,i5.5)')
'f', this%counter
683 fname = trim(this%fname(1:suffix_pos-1))//
'.'//id_str
685 call mpi_file_open(
neko_comm, trim(fname), &
686 mpi_mode_rdonly, mpi_info_null, fh, ierr)
688 if (ierr .ne. 0)
call neko_error(
"Could not read "//trim(fname))
690 call mpi_file_read_all(fh, hdr, 132, mpi_character, status, ierr)
693 read(hdr, 1) temp_str,fld_data_size, lx, ly, lz, glb_nelv, glb_nelv,&
694 time, counter, i, j, (rdcode(i),i=1,10)
695 1
format(4a,1x,i1,1x,i2,1x,i2,1x,i2,1x,i10,1x,i10,1x,e20.13,&
696 1x,i9,1x,i6,1x,i6,1x,10a)
697 if (data%nelv .eq. 0)
then
699 data%nelv = dist%num_local()
700 data%offset_el = dist%start_idx()
705 data%glb_nelv = glb_nelv
706 data%t_counter = counter
719 this%dp_precision = .true.
721 this%dp_precision = .false.
723 if (this%dp_precision)
then
724 allocate(
tmp_dp(data%gdim*n))
726 allocate(
tmp_sp(data%gdim*n))
732 read_velocity = .false.
733 read_pressure = .false.
735 if (rdcode(i) .eq.
'X')
then
737 if (data%x%n .ne. n)
call data%x%init(n)
738 if (data%y%n .ne. n)
call data%y%init(n)
739 if (data%z%n .ne. n)
call data%z%init(n)
742 if (rdcode(i) .eq.
'U')
then
743 read_velocity = .true.
744 if (data%u%n .ne. n)
call data%u%init(n)
745 if (data%v%n .ne. n)
call data%v%init(n)
746 if (data%w%n .ne. n)
call data%w%init(n)
749 if (rdcode(i) .eq.
'P')
then
750 read_pressure = .true.
751 if (data%p%n .ne. n)
call data%p%init(n)
754 if (rdcode(i) .eq.
'T')
then
756 if (data%t%n .ne. n)
call data%t%init(n)
760 if (rdcode(i) .eq.
'S')
then
762 read(rdcode(i),*) n_scalars
763 n_scalars = n_scalars*10
766 n_scalars = n_scalars+j
768 if (
allocated(data%s))
then
769 if (data%n_scalars .ne. n_scalars)
then
770 do j = 1, data%n_scalars
771 call data%s(j)%free()
774 data%n_scalars = n_scalars
775 allocate(data%s(n_scalars))
776 do j = 1, data%n_scalars
777 call data%s(j)%init(n)
781 data%n_scalars = n_scalars
782 allocate(data%s(data%n_scalars))
783 do j = 1, data%n_scalars
784 call data%s(j)%init(n)
791 call mpi_file_read_at_all(fh, mpi_offset, temp, 1, &
792 mpi_real, status, ierr)
793 if (temp .ne. test_pattern)
then
794 call neko_error(
'Incorrect format for fld file, test pattern does not match.')
799 if (
allocated(data%idx))
then
800 if (
size(data%idx) .ne. data%nelv)
then
802 allocate(data%idx(data%nelv))
805 allocate(data%idx(data%nelv))
808 byte_offset = mpi_offset + &
811 call mpi_file_read_at_all(fh, byte_offset, data%idx, data%nelv, &
812 mpi_integer, status, ierr)
814 mpi_offset = mpi_offset + int(data%glb_nelv, i8) * int(
mpi_integer_size, i8)
817 byte_offset = mpi_offset + int(data%offset_el, i8) * &
818 (int(data%gdim*lxyz, i8) * &
819 int(fld_data_size, i8))
821 mpi_offset = mpi_offset + int(data%glb_nelv, i8) * &
822 (int(data%gdim *lxyz, i8) * &
823 int(fld_data_size, i8))
826 if (read_velocity)
then
827 byte_offset = mpi_offset + int(data%offset_el, i8) * &
828 (int(data%gdim*lxyz, i8) * &
829 int(fld_data_size, i8))
831 mpi_offset = mpi_offset + int(data%glb_nelv, i8) * &
832 (int(data%gdim *lxyz, i8) * &
833 int(fld_data_size, i8))
836 if (read_pressure)
then
837 byte_offset = mpi_offset + int(data%offset_el, i8) * &
839 int(fld_data_size, i8))
841 mpi_offset = mpi_offset + int(data%glb_nelv, i8) * &
843 int(fld_data_size, i8))
847 byte_offset = mpi_offset + int(data%offset_el, i8) * &
849 int(fld_data_size, i8))
851 mpi_offset = mpi_offset + int(data%glb_nelv, i8) * &
853 int(fld_data_size, i8))
857 byte_offset = mpi_offset + int(data%offset_el, i8) * &
859 int(fld_data_size, i8))
861 mpi_offset = mpi_offset + int(data%glb_nelv, i8) * &
863 int(fld_data_size, i8))
866 this%counter = this%counter + 1
871 call neko_error(
'Currently we only read into fld_file_data_t, please use that data structure instead.')
880 integer(kind=MPI_OFFSET_KIND) :: byte_offset
882 type(mpi_status) :: status
883 integer :: n, ierr, lxyz, i, j, e
886 lxyz = fld_data%lx*fld_data%ly*fld_data%lz
888 if (this%dp_precision)
then
889 call mpi_file_read_at_all(fh, byte_offset,
tmp_dp, n, &
890 mpi_double_precision, status, ierr)
892 call mpi_file_read_at_all(fh, byte_offset,
tmp_sp, n, &
893 mpi_real, status, ierr)
896 if (this%dp_precision)
then
912 type(
vector_t),
intent(inout) :: x, y, z
914 integer(kind=MPI_OFFSET_KIND) :: byte_offset
916 type(mpi_status) :: status
917 integer :: n, ierr, lxyz, i, j, e, nd
921 lxyz = fld_data%lx*fld_data%ly*fld_data%lz
923 if (this%dp_precision)
then
924 call mpi_file_read_at_all(fh, byte_offset,
tmp_dp, nd, &
925 mpi_double_precision, status, ierr)
927 call mpi_file_read_at_all(fh, byte_offset,
tmp_sp, nd, &
928 mpi_real, status, ierr)
932 if (this%dp_precision)
then
934 do e = 1, fld_data%nelv
936 x%x((e-1)*lxyz+j) =
tmp_dp(i)
940 y%x((e-1)*lxyz+j) =
tmp_dp(i)
943 if (fld_data%gdim .eq. 3)
then
945 z%x((e-1)*lxyz+j) =
tmp_dp(i)
952 do e = 1, fld_data%nelv
954 x%x((e-1)*lxyz+j) =
tmp_sp(i)
958 y%x((e-1)*lxyz+j) =
tmp_sp(i)
961 if (fld_data%gdim .eq. 3)
then
963 z%x((e-1)*lxyz+j) =
tmp_sp(i)
974 integer,
intent(in) :: precision
976 if (precision .eq. dp)
then
977 this%dp_precision = .true.
978 else if (precision .eq. sp)
then
979 this%dp_precision = .false.
type(mpi_comm) neko_comm
MPI communicator.
integer pe_size
MPI size of 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...
real(kind=dp), dimension(:), allocatable, private tmp_dp
subroutine fld_file_set_precision(this, precision)
subroutine fld_file_read_vector_field(this, fh, byte_offset, x, y, z, fld_data)
subroutine fld_file_read(this, data)
Load a field from a NEKTON fld file.
subroutine fld_file_write_vector_field(this, fh, byte_offset, x, y, z, n, gdim, lxyz, nelv)
subroutine fld_file_write_metadata_vector(this, fh, byte_offset, x, y, z, gdim, lxyz, nelv)
real(kind=sp), dimension(:), allocatable, private tmp_sp
subroutine fld_file_read_field(this, fh, byte_offset, x, fld_data)
subroutine fld_file_write_field(this, fh, byte_offset, p, n)
subroutine fld_file_write_metadata_scalar(this, fh, byte_offset, x, lxyz, nelv)
subroutine fld_file_write(this, data, t)
Write fields to a NEKTON fld file.
real(kind=rp) function, public vlmin(vec, n)
minimun value of a vector of length n
real(kind=rp) function, public vlmax(vec, n)
maximum value of a vector of length n
Defines a mean flow field.
Defines a mean squared flow field.
integer, public mpi_double_precision_size
Size of MPI type double precision.
integer, public mpi_character_size
Size of MPI type character.
integer, public mpi_real_size
Size of MPI type real.
integer, public mpi_integer_size
Size of MPI type integer.
Defines a function space.
Defines structs that are used... Dont know if we should keep it though.
pure integer function filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
pure integer function filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
subroutine filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
Load-balanced linear distribution .
field_list_t, To be able to group fields together
Interface for NEKTON fld files.
The function space for the SEM solution fields.