Neko 1.99.6
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
bp_file.F90
Go to the documentation of this file.
1! Copyright (c) 2024, Gregor Weiss (HLRS)
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!
36module bp_file
39 use num_types, only : dp, sp, i8, rp
41 use field_list, only : field_list_t
42 use dofmap, only : dofmap_t
43 use vector, only : vector_t
44 use space, only : space_t
45 use mesh, only : mesh_t
46 use structs, only : array_ptr_t
48 use datadist, only : linear_dist_t
49 use comm, only : pe_size, pe_rank, neko_comm
50#ifdef HAVE_ADIOS2_FORTRAN
51 use adios2
52 use mpi_f08, only : mpi_bcast, mpi_character, mpi_integer
53#endif
54 use buffer_1d, only : buffer_1d_t
55 use buffer_4d, only : buffer_4d_t
57 use buffer, only : buffer_t
58 implicit none
59 private
60
61 class(buffer_t), private, allocatable :: outbuf_points
62 class(buffer_t), private, allocatable :: outbuf_npar
63
64#ifdef HAVE_ADIOS2_FORTRAN
65 type(adios2_adios) :: adios
66 type(adios2_io) :: iowriter
67 type(adios2_io) :: ioreader
68#endif
69
71 type, public, extends(generic_file_t) :: bp_file_t
72 logical :: dp_precision = .false.
73 integer :: layout = 1
74 contains
75 procedure :: read => bp_file_read
76 procedure :: write => bp_file_write
77 procedure :: get_next_output_fname => bp_file_get_next_output_fname
78 procedure :: set_precision => bp_file_set_precision
79 procedure :: set_layout => bp_file_set_layout
80 end type bp_file_t
81
82contains
83
85 function bp_file_get_next_output_fname(this) result(fname)
86 class(bp_file_t), intent(in) :: this
87 character(len=1024) :: fname
88 integer :: counter
89
90 counter = this%get_counter()
91 if (counter .eq. -1) then
92 counter = this%get_start_counter()
93 else
94 counter = counter + 1
95 end if
96
97 fname = bp_file_format_fname(this, counter)
98
100
102 function bp_file_format_fname(this, counter) result(fname)
103 class(bp_file_t), intent(in) :: this
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
109
110 base_fname = this%get_base_fname()
111 suffix_pos = filename_suffix_pos(base_fname)
112 write(id_str, '(i5.5,a)') counter, '.bp'
113 fname = trim(base_fname(1:suffix_pos-1)) // "0." // id_str
114
115 end function bp_file_format_fname
116
117#ifdef HAVE_ADIOS2_FORTRAN
118
119 subroutine bp_file_write(this, data, t)
120 class(bp_file_t), intent(inout) :: this
121 class(*), target, intent(in) :: data
122 real(kind=rp), intent(in), optional :: t
123 type(array_ptr_t) :: x, y, z, u, v, w, p, tem
124 type(mesh_t), pointer :: msh
125 type(dofmap_t), pointer :: dof
126 type(space_t), pointer :: xh
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
135 integer :: npar
136 integer, allocatable :: idx(:)
137 type(array_ptr_t), allocatable :: scalar_fields(:)
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
145 integer :: file_unit
146
147 if (present(t)) then
148 time = real(t, dp)
149 else
150 time = 0.0_rp
151 end if
152
153 nullify(msh)
154 nullify(dof)
155 nullify(xh)
156 n_scalar_fields = 0
157 write_velocity = .false.
158 write_pressure = .false.
159 write_temperature = .false.
160
162 select type (data)
163 type is (fld_file_data_t)
164 npar = data%size()
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
169 u%ptr => data%u%x
170 write_velocity = .true.
171 end if
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
175 p%ptr => data%p%x
176 write_pressure = .true.
177 end if
178 if (data%t%size() .gt. 0) then
179 write_temperature = .true.
180 tem%ptr => data%t%x
181 end if
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
186 end do
187 nelv = data%nelv
188 lx = data%lx
189 ly = data%ly
190 lz = data%lz
191 gdim = data%gdim
192 glb_nelv = data%glb_nelv
193 offset_el = data%offset_el
194
195 allocate(idx(nelv))
196 do i = 1, nelv
197 idx(i) = data%idx(i)
198 end do
199 type is (field_list_t)
200 npar = data%size()
201 select case (data%size())
202 case (1)
203 p%ptr => data%items(1)%ptr%x(:,1,1,1)
204 write_pressure = .true.
205 case (2)
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.
210 case (3)
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.
215 case (4)
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.
222 case (5:99)
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)
227 ! Check if position 5 is a temperature field by name
228 if (trim(data%name(5)) .eq. 'temperature') then
229 ! Position 5 is temperature, remaining fields are scalars
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)
235 end do
236 write_temperature = .true.
237 else
238 ! All remaining fields are scalars (no temperature field)
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)
243 end do
244 write_temperature = .false.
245 end if
246 write_pressure = .true.
247 write_velocity = .true.
248 case default
249 call neko_error('This many fields not supported yet, bp_file')
250 end select
251 dof => data%dof(1)
252 class default
253 call neko_error('Invalid data')
254 end select
255
256 ! Fix things for pointers that do not exist in all data types...
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)
261 msh => dof%msh
262 xh => dof%Xh
263 end if
264
265 if (associated(msh)) then
266 nelv = msh%nelv
267 glb_nelv = msh%glb_nelv
268 offset_el = msh%offset_el
269 gdim = msh%gdim
270 ! Store global idx of each element
271 allocate(idx(msh%nelv))
272 do i = 1, msh%nelv
273 idx(i) = msh%elements(i)%e%id()
274 end do
275 end if
276
277 if (associated(xh)) then
278 lx = xh%lx
279 ly = xh%ly
280 lz = xh%lz
281 end if
282
283 lxyz = lx*ly*lz
284 n = nelv*lxyz
285
286 if (this%dp_precision) then
287 adios2_type = adios2_type_dp
288 else
289 adios2_type = adios2_type_real
290 end if
291
292 if (.not. allocated(outbuf_points)) allocate(buffer_1d_t::outbuf_points)
293 call outbuf_points%init(this%dp_precision, gdim, glb_nelv, offset_el, &
294 nelv, lx, ly, lz)
295
296 write(*,*) "writing layout ", this%layout
297 if (.not. allocated(outbuf_npar)) then
298 if (this%layout .eq. 1) then
299 allocate(buffer_1d_t::outbuf_npar)
300 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
301 nelv, lx, ly, lz)
302 else if (this%layout .eq. 2) then
303 allocate(buffer_4d_t::outbuf_npar)
304 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
305 nelv, lx, ly, lz)
306 else if (this%layout .eq. 4) then
308 call outbuf_npar%init(this%dp_precision, npar, glb_nelv, offset_el, &
309 nelv, lx, ly, lz)
310 else
311 call neko_error('Invalid buffer')
312 end if
313 end if
314
315 !
316 ! Create fld header for NEKTON's multifile output
317 !
318
319 call this%increment_counter()
320 write_mesh = (this%get_counter() .eq. this%get_start_counter())
321
322 ! Build rdcode note that for field_t, we only support scalar
323 ! fields at the moment
324 rdcode = ' '
325 i = 1
326 if (write_mesh) then
327 rdcode(i) = 'X'
328 i = i + 1
329 end if
330 if (write_velocity) then
331 rdcode(i) = 'U'
332 i = i + 1
333 end if
334 if (write_pressure) then
335 rdcode(i) = 'P'
336 i = i + 1
337 end if
338 if (write_temperature) then
339 rdcode(i) = 'T'
340 i = i + 1
341 end if
342 if (n_scalar_fields .gt. 0 ) then
343 rdcode(i) = 'S'
344 i = i + 1
345 write(rdcode(i), '(i1)') (n_scalar_fields)/10
346 i = i + 1
347 write(rdcode(i), '(i1)') (n_scalar_fields) - 10*((n_scalar_fields)/10)
348 i = i + 1
349 end if
350
351 ! Create binary header information
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)
356
357 ! Adapt filename with counter
359 base_fname = this%get_base_fname()
360 suffix_pos = filename_suffix_pos(base_fname)
361 fname = bp_file_format_fname(this, this%get_counter())
362
363 if (.not. adios%valid) then
365 call adios2_init(adios, 'adios2.xml', neko_comm%mpi_val, ierr)
366 end if
367
368 if (.not. iowriter%valid) then
369 call adios2_declare_io(iowriter, adios, 'writer', ierr)
370 call adios2_set_engine(iowriter, 'BP5', ierr)
371 end if
372
373 call adios2_open(bpwriter, iowriter, trim(fname), adios2_mode_write, &
374 neko_comm%mpi_val, ierr)
375 call adios2_begin_step(bpwriter, ierr)
376
377 ! Write header
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)
382 end if
383 call adios2_put(bpwriter, variable_hdr, hdr, adios2_mode_sync, ierr)
384
385 ! Write element idxs
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)
394 else
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)
398 end if
399 call adios2_put(bpwriter, variable_idx, idx, adios2_mode_sync, ierr)
400
401 deallocate(idx)
402
403 if (write_mesh) then
404 call outbuf_points%fill(x%ptr, n)
405 call outbuf_points%define(variable, iowriter, 'points-x', ierr)
406 call outbuf_points%write(bpwriter, variable, ierr)
407 call outbuf_points%fill(y%ptr, n)
408 call outbuf_points%define(variable, iowriter, 'points-y', ierr)
409 call outbuf_points%write(bpwriter, variable, ierr)
410 call outbuf_points%fill(z%ptr, n)
411 call outbuf_points%define(variable, iowriter, 'points-z', ierr)
412 call outbuf_points%write(bpwriter, variable, ierr)
413 end if
414
415 if (write_velocity) then
416 call outbuf_npar%fill(u%ptr, n)
417 if (this%layout .le. 3) then
418 call outbuf_npar%define(variable, iowriter, 'velocity-u', ierr)
419 call outbuf_npar%write(bpwriter, variable, ierr)
420 end if
421 call outbuf_npar%fill(v%ptr, n)
422 if (this%layout .le. 3) then
423 call outbuf_npar%define(variable, iowriter, 'velocity-v', ierr)
424 call outbuf_npar%write(bpwriter, variable, ierr)
425 end if
426 call outbuf_npar%fill(w%ptr, n)
427 if (this%layout .le. 3) then
428 call outbuf_npar%define(variable, iowriter, 'velocity-w', ierr)
429 call outbuf_npar%write(bpwriter, variable, ierr)
430 end if
431 end if
432
433 if (write_pressure) then
434 call outbuf_npar%fill(p%ptr, n)
435 if (this%layout .le. 3) then
436 call outbuf_npar%define(variable, iowriter, 'pressure', ierr)
437 call outbuf_npar%write(bpwriter, variable, ierr)
438 end if
439 end if
440
441 if (write_temperature) then
442 call outbuf_npar%fill(tem%ptr, n)
443 if (this%layout .le. 3) then
444 call outbuf_npar%define(variable, iowriter, 'temperature', ierr)
445 call outbuf_npar%write(bpwriter, variable, ierr)
446 end if
447 end if
448
449 do i = 1, n_scalar_fields
450 call outbuf_npar%fill(scalar_fields(i)%ptr, n)
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)
454 call outbuf_npar%write(bpwriter, variable, ierr)
455 end if
456 end do
457
458 if (this%layout .gt. 3) then
459 call outbuf_npar%define(variable, iowriter, 'fields', ierr)
460 call outbuf_npar%write(bpwriter, variable, ierr)
461 end if
462
463 call adios2_end_step(bpwriter, ierr)
464 call adios2_close(bpwriter, ierr)
465
466 ! Write metadata file
467 if (pe_rank .eq. 0) then
468 tslash_pos = filename_tslash_pos(base_fname)
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'
480 close(file_unit)
481 end if
482
483 if (allocated(outbuf_points)) deallocate(outbuf_points)
484 if (allocated(outbuf_npar)) deallocate(outbuf_npar)
485 end subroutine bp_file_write
486
488 subroutine bp_file_read(this, data)
489 class(bp_file_t) :: this
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
495 logical :: read_temp
496 character(len=8) :: id_str
497 integer :: lx, ly, lz, glb_nelv, counter, lxyz
498 integer :: npar
499 integer :: adios2_type, n_scalars, n
500 real(kind=rp) :: time
501 type(linear_dist_t) :: dist
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
507 integer :: file_unit
508
509 select type (data)
510 type is (fld_file_data_t)
511 base_fname = this%get_base_fname()
512 suffix_pos = filename_suffix_pos(base_fname)
513 meta_fname = trim(base_fname(1:suffix_pos-1))
514 call filename_chsuffix(meta_fname, meta_fname, 'adios2')
515
517 inquire(file = trim(meta_fname), exist = meta_file)
518 if (meta_file .and. data%meta_nsamples .eq. 0) then
519 if (pe_rank .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
530
531 close(file_unit)
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
536 end if
537 call mpi_bcast(data%fld_series_fname, 1024, mpi_character, 0, &
538 neko_comm, ierr)
539 call mpi_bcast(data%meta_start_counter, 1, mpi_integer, 0, &
540 neko_comm, ierr)
541 call mpi_bcast(data%meta_nsamples, 1, mpi_integer, 0, &
542 neko_comm, ierr)
543 if (this%get_counter() .eq. 0) &
544 call this%set_counter(data%meta_start_counter)
545 end if
546
547 if (meta_file) then
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')
553 end if
554 else
555 ! @todo write into function because of code duplication
556 !suffix_pos = filename_suffix_pos(base_fname)
557 !write(id_str, '(i5.5,a)') this%get_counter(), '.bp'
558 !fname = trim(base_fname(1:suffix_pos-1))//'.'//id_str
559 fname = base_fname
560 end if
561
562 if (.not.adios%valid) then
563 ! @todo enable parsing XML filename
564 call adios2_init(adios, 'adios2.xml', neko_comm%mpi_val, ierr)
565 end if
566 if (.not.ioreader%valid) then
567 call adios2_declare_io(ioreader, adios, 'reader', ierr)
568 call adios2_set_engine(ioreader, 'BP5', ierr)
569 end if
570
571 ! @todo check if engines and variables should be brought in to local
572 ! subroutine scope
573 call adios2_open(bpreader, ioreader, trim(fname), adios2_mode_read, &
574 neko_comm%mpi_val, ierr)
575 call adios2_begin_step(bpreader, ierr)
576
577 ! Read header and adjust data accordingly
578 if (.not.variable_hdr%valid) then
579 call adios2_inquire_variable(variable_hdr, ioreader, 'header', ierr)
580 end if
581 call adios2_get(bpreader, variable_hdr, hdr, adios2_mode_sync, ierr)
582
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
588 dist = linear_dist_t(glb_nelv, pe_rank, pe_size, neko_comm)
589 data%nelv = dist%num_local()
590 data%offset_el = dist%start_idx()
591 end if
592 data%lx = lx
593 data%ly = ly
594 data%lz = lz
595 data%glb_nelv = glb_nelv
596 data%t_counter = counter
597 data%time = time
598 lxyz = lx * ly * lz
599 n = lxyz * data%nelv
600
601 if (lz .eq. 1) then
602 data%gdim = 2
603 else
604 data%gdim = 3
605 end if
606
607 if (adios2_type .eq. adios2_type_dp) then
608 this%dp_precision = .true.
609 else
610 this%dp_precision = .false.
611 end if
612
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)
616
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
623 if (.not. allocated(inpbuf)) allocate(buffer_4d_npar_t::inpbuf)
624 end if
625
626 select type (inpbuf)
627 type is (buffer_1d_t)
628 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
629 data%offset_el, data%nelv, lx, ly, lz)
630 type is (buffer_4d_t)
631 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
632 data%offset_el, data%nelv, lx, ly, lz)
633 type is (buffer_4d_npar_t)
634 call inpbuf%init(this%dp_precision, npar, data%glb_nelv, &
635 data%offset_el, data%nelv, lx, ly, lz)
636 class default
637 call neko_error('Invalid buffer')
638 end select
639
640 i = 1
641 read_mesh = .false.
642 read_velocity = .false.
643 read_pressure = .false.
644 read_temp = .false.
645 if (rdcode(i) .eq. 'X') then
646 read_mesh = .true.
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)
650 i = i + 1
651 end if
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)
657 i = i + 1
658 end if
659 if (rdcode(i) .eq. 'P') then
660 read_pressure = .true.
661 if (data%p%size() .ne. n) call data%p%init(n)
662 i = i + 1
663 end if
664 if (rdcode(i) .eq. 'T') then
665 read_temp = .true.
666 if (data%t%size() .ne. n) call data%t%init(n)
667 i = i + 1
668 end if
669 n_scalars = 0
670 if (rdcode(i) .eq. 'S') then
671 i = i + 1
672 read(rdcode(i),*) n_scalars
673 n_scalars = n_scalars*10
674 i = i + 1
675 read(rdcode(i),*) j
676 n_scalars = n_scalars+j
677 i = i + 1
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()
682 end do
683 deallocate(data%s)
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)
688 end do
689 end if
690 else
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)
695 end do
696 end if
697 i = i + 1
698 end if
699
700 if (allocated(data%idx)) then
701 if (size(data%idx) .ne. data%nelv) then
702 deallocate(data%idx)
703 allocate(data%idx(data%nelv))
704 end if
705 else
706 allocate(data%idx(data%nelv))
707 end if
708
709 ! Read element idxs
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)
716 end if
717 call adios2_get(bpreader, variable_idx, data%idx, adios2_mode_sync, ierr)
718
719 if (read_mesh) then
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)
729 end if
730
731 if (this%layout .eq. 3) then
732 call inpbuf%inquire(variable, ioreader, 'fields', ierr)
733 call inpbuf%read(bpreader, variable, ierr)
734 end if
735
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)
740 end if
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)
745 end if
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)
750 end if
751 call inpbuf%copy(data%w)
752 end if
753
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)
758 end if
759 call inpbuf%copy(data%p)
760 end if
761
762 if (read_temp) then
763 if (this%layout .le. 3) then
764 call inpbuf%inquire(variable, ioreader, 'temperature', ierr)
765 call inpbuf%read(bpreader, variable, ierr)
766 end if
767 call inpbuf%copy(data%t)
768 end if
769
770 do i = 1, n_scalars
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)
775 end if
776 call inpbuf%copy(data%s(i))
777 end do
778
779 call adios2_end_step(bpreader, ierr)
780 call adios2_close(bpreader, ierr)
781
782 call this%increment_counter()
783
784 if (allocated(inpbuf_points)) deallocate(inpbuf_points)
785 if (allocated(inpbuf)) deallocate(inpbuf)
786 class default
787 call neko_error('Currently we only read into fld_file_data_t,&
788 please use that data structure instead.&
789 (output_format.adios2)')
790 end select
791
792 end subroutine bp_file_read
793
794#else
795
796 subroutine bp_file_write(this, data, t)
797 class(bp_file_t), intent(inout) :: this
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')
801 end subroutine bp_file_write
802
803 subroutine bp_file_read(this, data)
804 class(bp_file_t) :: this
805 class(*), target, intent(inout) :: data
806 call neko_error('Neko needs to be built with ADIOS2 Fortran support')
807 end subroutine bp_file_read
808
809#endif
810
811 subroutine bp_file_set_precision(this, precision)
812 class(bp_file_t) :: this
813 integer, intent(in) :: precision
814
815 if (precision .eq. dp) then
816 this%dp_precision = .true.
817 else if (precision .eq. sp) then
818 this%dp_precision = .false.
819 else
820 call neko_error('Invalid precision')
821 end if
822
823 end subroutine bp_file_set_precision
824
825 subroutine bp_file_set_layout(this, layout)
826 class(bp_file_t) :: this
827 integer, intent(in) :: layout
828
830 if (layout .ge. 1 .and. layout .le. 3) then
831 this%layout = layout
832 else
833 call neko_error('Invalid data layout')
834 end if
835
836 end subroutine bp_file_set_layout
837
838end module bp_file
double real
ADIOS2 bp file format.
Definition bp_file.F90:36
subroutine bp_file_read(this, data)
Definition bp_file.F90:804
class(buffer_t), allocatable, private outbuf_npar
Definition bp_file.F90:62
character(len=1024) function bp_file_format_fname(this, counter)
Format the physical file name for a counter value.
Definition bp_file.F90:103
character(len=1024) function bp_file_get_next_output_fname(this)
Get the physical file name generated by the next write.
Definition bp_file.F90:86
class(buffer_t), allocatable, private outbuf_points
Definition bp_file.F90:61
subroutine bp_file_write(this, data, t)
Definition bp_file.F90:797
subroutine bp_file_set_layout(this, layout)
Definition bp_file.F90:826
subroutine bp_file_set_precision(this, precision)
Definition bp_file.F90:812
Generic buffer that is extended with buffers of varying rank.
Definition buffer_1d.F90:34
Generic buffer that is extended with buffers of varying rank.
integer, private npar
Generic buffer that is extended with buffers of varying rank.
Definition buffer_4d.F90:34
Generic buffer that is extended with buffers of varying rank.
Definition buffer.F90:34
Definition comm.F90:1
integer, public pe_size
MPI size of communicator.
Definition comm.F90:62
integer, public pe_rank
MPI rank.
Definition comm.F90:59
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
Defines practical data distributions.
Definition datadist.f90:34
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Module for file I/O operations.
Definition file.f90:34
Simple module to handle fld file series. Provides an interface to the different fields sotred in a fl...
Defines a mesh.
Definition mesh.f90:34
integer, parameter, public i2
Definition num_types.f90:5
integer, parameter, public i8
Definition num_types.f90:7
integer, parameter, public dp
Definition num_types.f90:9
integer, parameter, public sp
Definition num_types.f90:8
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Defines a function space.
Definition space.f90:34
Defines structs that are used... Dont know if we should keep it though.
Definition structs.f90:2
Utilities.
Definition utils.f90:35
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
Definition utils.f90:156
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
Definition utils.f90:81
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Definition utils.f90:74
Defines a vector.
Definition vector.f90:34
Interface for ADIOS2 bp files.
Definition bp_file.F90:71
Load-balanced linear distribution .
Definition datadist.f90:50
field_list_t, To be able to group fields together
A generic file handler.
The function space for the SEM solution fields.
Definition space.f90:64
Pointer to array.
Definition structs.f90:14