Neko 1.99.1
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
37 use num_types, only : dp, sp, i8, rp
39 use field_list, only : field_list_t
40 use dofmap, only : dofmap_t
41 use vector, only : vector_t
42 use space, only : space_t
43 use mesh, only : mesh_t
44 use structs, only : array_ptr_t
46 use utils, only : neko_error
47 use datadist, only : linear_dist_t
48 use comm, only : pe_size, pe_rank, neko_comm
49#ifdef HAVE_ADIOS2_FORTRAN
50 use adios2
51 use mpi_f08, only : mpi_bcast, mpi_character, mpi_integer
52#endif
53 use buffer_1d, only : buffer_1d_t
54 use buffer_4d, only : buffer_4d_t
56 use buffer, only : buffer_t
57 implicit none
58 private
59
60 class(buffer_t), private, allocatable :: outbuf_points
61 class(buffer_t), private, allocatable :: outbuf_npar
62
63#ifdef HAVE_ADIOS2_FORTRAN
64 type(adios2_adios) :: adios
65 type(adios2_io) :: iowriter
66 type(adios2_io) :: ioreader
67#endif
68
70 type, public, extends(generic_file_t) :: bp_file_t
71 logical :: dp_precision = .false.
72 integer :: layout = 1
73 contains
74 procedure :: read => bp_file_read
75 procedure :: write => bp_file_write
76 procedure :: set_precision => bp_file_set_precision
77 procedure :: set_layout => bp_file_set_layout
78 end type bp_file_t
79
80contains
81
82#ifdef HAVE_ADIOS2_FORTRAN
83
84 subroutine bp_file_write(this, data, t)
85 class(bp_file_t), intent(inout) :: this
86 class(*), target, intent(in) :: data
87 real(kind=rp), intent(in), optional :: t
88 type(array_ptr_t) :: x, y, z, u, v, w, p, tem
89 type(mesh_t), pointer :: msh
90 type(dofmap_t), pointer :: dof
91 type(space_t), pointer :: xh
92 real(kind=dp) :: time
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
100 integer :: npar
101 integer, allocatable :: idx(:)
102 type(array_ptr_t), allocatable :: scalar_fields(:)
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
110 integer :: file_unit
111
112 if (present(t)) then
113 time = real(t, dp)
114 else
115 time = 0.0_rp
116 end if
117
118 nullify(msh)
119 nullify(dof)
120 nullify(xh)
121 n_scalar_fields = 0
122 write_velocity = .false.
123 write_pressure = .false.
124 write_temperature = .false.
125
127 select type (data)
128 type is (fld_file_data_t)
129 npar = data%size()
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
134 u%ptr => data%u%x
135 write_velocity = .true.
136 end if
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
140 p%ptr => data%p%x
141 write_pressure = .true.
142 end if
143 if (data%t%n .gt. 0) then
144 write_temperature = .true.
145 tem%ptr => data%t%x
146 end if
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
151 end do
152 nelv = data%nelv
153 lx = data%lx
154 ly = data%ly
155 lz = data%lz
156 gdim = data%gdim
157 glb_nelv = data%glb_nelv
158 offset_el = data%offset_el
159
160 allocate(idx(nelv))
161 do i = 1, nelv
162 idx(i) = data%idx(i)
163 end do
164 type is (field_list_t)
165 npar = data%size()
166 select case (data%size())
167 case (1)
168 p%ptr => data%items(1)%ptr%x(:,1,1,1)
169 write_pressure = .true.
170 case (2)
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.
175 case (3)
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.
180 case (4)
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.
187 case (5:99)
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)
192 ! Check if position 5 is a temperature field by name
193 if (trim(data%name(5)) .eq. 'temperature') then
194 ! Position 5 is temperature, remaining fields are scalars
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)
200 end do
201 write_temperature = .true.
202 else
203 ! All remaining fields are scalars (no temperature field)
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)
208 end do
209 write_temperature = .false.
210 end if
211 write_pressure = .true.
212 write_velocity = .true.
213 case default
214 call neko_error('This many fields not supported yet, bp_file')
215 end select
216 dof => data%dof(1)
217 class default
218 call neko_error('Invalid data')
219 end select
220
221 ! Fix things for pointers that do not exist in all data types...
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)
226 msh => dof%msh
227 xh => dof%Xh
228 end if
229
230 if (associated(msh)) then
231 nelv = msh%nelv
232 glb_nelv = msh%glb_nelv
233 offset_el = msh%offset_el
234 gdim = msh%gdim
235 ! Store global idx of each element
236 allocate(idx(msh%nelv))
237 do i = 1, msh%nelv
238 idx(i) = msh%elements(i)%e%id()
239 end do
240 end if
241
242 if (associated(xh)) then
243 lx = xh%lx
244 ly = xh%ly
245 lz = xh%lz
246 end if
247
248 lxyz = lx*ly*lz
249 n = nelv*lxyz
250
251 if (this%dp_precision) then
252 adios2_type = adios2_type_dp
253 else
254 adios2_type = adios2_type_real
255 end if
256
257 if (.not. allocated(outbuf_points)) allocate(buffer_1d_t::outbuf_points)
258 call outbuf_points%init(this%dp_precision, gdim, glb_nelv, offset_el, &
259 nelv, lx, ly, lz)
260
261 write(*,*) "writing layout ", this%layout
262 if (.not. allocated(outbuf_npar)) then
263 if (this%layout .eq. 1) then
264 allocate(buffer_1d_t::outbuf_npar)
265 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
266 nelv, lx, ly, lz)
267 else if (this%layout .eq. 2) then
268 allocate(buffer_4d_t::outbuf_npar)
269 call outbuf_npar%init(this%dp_precision, gdim, glb_nelv, offset_el, &
270 nelv, lx, ly, lz)
271 else if (this%layout .eq. 4) then
273 call outbuf_npar%init(this%dp_precision, npar, glb_nelv, offset_el, &
274 nelv, lx, ly, lz)
275 else
276 call neko_error('Invalid buffer')
277 end if
278 end if
279
280 !
281 ! Create fld header for NEKTON's multifile output
282 !
283
284 write_mesh = (this%counter .eq. this%start_counter)
285
286 ! Build rdcode note that for field_t, we only support scalar
287 ! fields at the moment
288 rdcode = ' '
289 i = 1
290 if (write_mesh) then
291 rdcode(i) = 'X'
292 i = i + 1
293 end if
294 if (write_velocity) then
295 rdcode(i) = 'U'
296 i = i + 1
297 end if
298 if (write_pressure) then
299 rdcode(i) = 'P'
300 i = i + 1
301 end if
302 if (write_temperature) then
303 rdcode(i) = 'T'
304 i = i + 1
305 end if
306 if (n_scalar_fields .gt. 0 ) then
307 rdcode(i) = 'S'
308 i = i + 1
309 write(rdcode(i), '(i1)') (n_scalar_fields)/10
310 i = i + 1
311 write(rdcode(i), '(i1)') (n_scalar_fields) - 10*((n_scalar_fields)/10)
312 i = i + 1
313 end if
314
315 ! Create binary header information
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)
320
321 ! Adapt filename with counter
324 base_fname = this%get_base_fname()
325 suffix_pos = filename_suffix_pos(base_fname)
326 write(id_str, '(i5.5,a)') this%counter, '.bp'
327 fname = trim(base_fname(1:suffix_pos-1)) // "0." // id_str
328
329 if (.not. adios%valid) then
331 call adios2_init(adios, 'adios2.xml', neko_comm%mpi_val, ierr)
332 end if
333
334 if (.not. iowriter%valid) then
335 call adios2_declare_io(iowriter, adios, 'writer', ierr)
336 call adios2_set_engine(iowriter, 'BP5', ierr)
337 end if
338
339 call adios2_open(bpwriter, iowriter, trim(fname), adios2_mode_write, &
340 neko_comm%mpi_val, ierr)
341 call adios2_begin_step(bpwriter, ierr)
342
343 ! Write header
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)
348 end if
349 call adios2_put(bpwriter, variable_hdr, hdr, adios2_mode_sync, ierr)
350
351 ! Write element idxs
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)
360 else
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)
364 end if
365 call adios2_put(bpwriter, variable_idx, idx, adios2_mode_sync, ierr)
366
367 deallocate(idx)
368
369 if (write_mesh) then
370 call outbuf_points%fill(x%ptr, n)
371 call outbuf_points%define(variable, iowriter, 'points-x', ierr)
372 call outbuf_points%write(bpwriter, variable, ierr)
373 call outbuf_points%fill(y%ptr, n)
374 call outbuf_points%define(variable, iowriter, 'points-y', ierr)
375 call outbuf_points%write(bpwriter, variable, ierr)
376 call outbuf_points%fill(z%ptr, n)
377 call outbuf_points%define(variable, iowriter, 'points-z', ierr)
378 call outbuf_points%write(bpwriter, variable, ierr)
379 end if
380
381 if (write_velocity) then
382 call outbuf_npar%fill(u%ptr, n)
383 if (this%layout .le. 3) then
384 call outbuf_npar%define(variable, iowriter, 'velocity-u', ierr)
385 call outbuf_npar%write(bpwriter, variable, ierr)
386 end if
387 call outbuf_npar%fill(v%ptr, n)
388 if (this%layout .le. 3) then
389 call outbuf_npar%define(variable, iowriter, 'velocity-v', ierr)
390 call outbuf_npar%write(bpwriter, variable, ierr)
391 end if
392 call outbuf_npar%fill(w%ptr, n)
393 if (this%layout .le. 3) then
394 call outbuf_npar%define(variable, iowriter, 'velocity-w', ierr)
395 call outbuf_npar%write(bpwriter, variable, ierr)
396 end if
397 end if
398
399 if (write_pressure) then
400 call outbuf_npar%fill(p%ptr, n)
401 if (this%layout .le. 3) then
402 call outbuf_npar%define(variable, iowriter, 'pressure', ierr)
403 call outbuf_npar%write(bpwriter, variable, ierr)
404 end if
405 end if
406
407 if (write_temperature) then
408 call outbuf_npar%fill(tem%ptr, n)
409 if (this%layout .le. 3) then
410 call outbuf_npar%define(variable, iowriter, 'temperature', ierr)
411 call outbuf_npar%write(bpwriter, variable, ierr)
412 end if
413 end if
414
415 do i = 1, n_scalar_fields
416 call outbuf_npar%fill(scalar_fields(i)%ptr, n)
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)
420 call outbuf_npar%write(bpwriter, variable, ierr)
421 end if
422 end do
423
424 if (this%layout .gt. 3) then
425 call outbuf_npar%define(variable, iowriter, 'fields', ierr)
426 call outbuf_npar%write(bpwriter, variable, ierr)
427 end if
428
429 call adios2_end_step(bpwriter, ierr)
430 call adios2_close(bpwriter, ierr)
431
432 ! Write metadata file
433 if (pe_rank .eq. 0) then
434 tslash_pos = filename_tslash_pos(base_fname)
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'
445 close(file_unit)
446 end if
447
448 this%counter = this%counter + 1
449
450 if (allocated(outbuf_points)) deallocate(outbuf_points)
451 if (allocated(outbuf_npar)) deallocate(outbuf_npar)
452 end subroutine bp_file_write
453
455 subroutine bp_file_read(this, data)
456 class(bp_file_t) :: this
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
462 logical :: read_temp
463 character(len=8) :: id_str
464 integer :: lx, ly, lz, glb_nelv, counter, lxyz
465 integer :: npar
466 integer :: adios2_type, n_scalars, n
467 real(kind=rp) :: time
468 type(linear_dist_t) :: dist
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
474 integer :: file_unit
475
476 select type (data)
477 type is (fld_file_data_t)
478 base_fname = this%get_base_fname()
479 suffix_pos = filename_suffix_pos(base_fname)
480 meta_fname = trim(base_fname(1:suffix_pos-1))
481 call filename_chsuffix(meta_fname, meta_fname,'adios2')
482
484 inquire(file = trim(meta_fname), exist = meta_file)
485 if (meta_file .and. data%meta_nsamples .eq. 0) then
486 if (pe_rank .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
497
498 close(file_unit)
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
503 end if
504 call mpi_bcast(data%fld_series_fname, 1024, mpi_character, 0, &
505 neko_comm, ierr)
506 call mpi_bcast(data%meta_start_counter, 1, mpi_integer, 0, &
507 neko_comm, ierr)
508 call mpi_bcast(data%meta_nsamples, 1, mpi_integer, 0, &
509 neko_comm, ierr)
510 if (this%counter .eq. 0) this%counter = data%meta_start_counter
511 end if
512
513 if (meta_file) then
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')
518 end if
519 else
520 ! @todo write into function because of code duplication
521 !suffix_pos = filename_suffix_pos(base_fname)
522 !write(id_str, '(i5.5,a)') this%counter, '.bp'
523 !fname = trim(base_fname(1:suffix_pos-1))//'.'//id_str
524 fname = base_fname
525 end if
526
527 if (.not.adios%valid) then
528 ! @todo enable parsing XML filename
529 call adios2_init(adios, 'adios2.xml', neko_comm%mpi_val, ierr)
530 end if
531 if (.not.ioreader%valid) then
532 call adios2_declare_io(ioreader, adios, 'reader', ierr)
533 call adios2_set_engine(ioreader, 'BP5', ierr)
534 end if
535
536 ! @todo check if engines and variables should be brought in to local
537 ! subroutine scope
538 call adios2_open(bpreader, ioreader, trim(fname), adios2_mode_read, &
539 neko_comm%mpi_val, ierr)
540 call adios2_begin_step(bpreader, ierr)
541
542 ! Read header and adjust data accordingly
543 if (.not.variable_hdr%valid) then
544 call adios2_inquire_variable(variable_hdr, ioreader, 'header', ierr)
545 end if
546 call adios2_get(bpreader, variable_hdr, hdr, adios2_mode_sync, ierr)
547
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
553 dist = linear_dist_t(glb_nelv, pe_rank, pe_size, neko_comm)
554 data%nelv = dist%num_local()
555 data%offset_el = dist%start_idx()
556 end if
557 data%lx = lx
558 data%ly = ly
559 data%lz = lz
560 data%glb_nelv = glb_nelv
561 data%t_counter = counter
562 data%time = time
563 lxyz = lx * ly * lz
564 n = lxyz * data%nelv
565
566 if (lz .eq. 1) then
567 data%gdim = 2
568 else
569 data%gdim = 3
570 end if
571
572 if (adios2_type .eq. adios2_type_dp) then
573 this%dp_precision = .true.
574 else
575 this%dp_precision = .false.
576 end if
577
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)
581
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
588 if (.not. allocated(inpbuf)) allocate(buffer_4d_npar_t::inpbuf)
589 end if
590
591 select type (inpbuf)
592 type is (buffer_1d_t)
593 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
594 data%offset_el, data%nelv, lx, ly, lz)
595 type is (buffer_4d_t)
596 call inpbuf%init(this%dp_precision, data%gdim, data%glb_nelv, &
597 data%offset_el, data%nelv, lx, ly, lz)
598 type is (buffer_4d_npar_t)
599 call inpbuf%init(this%dp_precision, npar, data%glb_nelv, &
600 data%offset_el, data%nelv, lx, ly, lz)
601 class default
602 call neko_error('Invalid buffer')
603 end select
604
605 i = 1
606 read_mesh = .false.
607 read_velocity = .false.
608 read_pressure = .false.
609 read_temp = .false.
610 if (rdcode(i) .eq. 'X') then
611 read_mesh = .true.
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)
615 i = i + 1
616 end if
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)
622 i = i + 1
623 end if
624 if (rdcode(i) .eq. 'P') then
625 read_pressure = .true.
626 if (data%p%n .ne. n) call data%p%init(n)
627 i = i + 1
628 end if
629 if (rdcode(i) .eq. 'T') then
630 read_temp = .true.
631 if (data%t%n .ne. n) call data%t%init(n)
632 i = i + 1
633 end if
634 n_scalars = 0
635 if (rdcode(i) .eq. 'S') then
636 i = i + 1
637 read(rdcode(i),*) n_scalars
638 n_scalars = n_scalars*10
639 i = i + 1
640 read(rdcode(i),*) j
641 n_scalars = n_scalars+j
642 i = i + 1
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()
647 end do
648 deallocate(data%s)
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)
653 end do
654 end if
655 else
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)
660 end do
661 end if
662 i = i + 1
663 end if
664
665 if (allocated(data%idx)) then
666 if (size(data%idx) .ne. data%nelv) then
667 deallocate(data%idx)
668 allocate(data%idx(data%nelv))
669 end if
670 else
671 allocate(data%idx(data%nelv))
672 end if
673
674 ! Read element idxs
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)
681 end if
682 call adios2_get(bpreader, variable_idx, data%idx, adios2_mode_sync, ierr)
683
684 if (read_mesh) then
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)
694 end if
695
696 if (this%layout .eq. 3) then
697 call inpbuf%inquire(variable, ioreader, 'fields', ierr)
698 call inpbuf%read(bpreader, variable, ierr)
699 end if
700
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)
705 end if
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)
710 end if
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)
715 end if
716 call inpbuf%copy(data%w)
717 end if
718
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)
723 end if
724 call inpbuf%copy(data%p)
725 end if
726
727 if (read_temp) then
728 if (this%layout .le. 3) then
729 call inpbuf%inquire(variable, ioreader, 'temperature', ierr)
730 call inpbuf%read(bpreader, variable, ierr)
731 end if
732 call inpbuf%copy(data%t)
733 end if
734
735 do i = 1, n_scalars
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)
740 end if
741 call inpbuf%copy(data%s(i))
742 end do
743
744 call adios2_end_step(bpreader, ierr)
745 call adios2_close(bpreader, ierr)
746
747 this%counter = this%counter + 1
748
749 if (allocated(inpbuf_points)) deallocate(inpbuf_points)
750 if (allocated(inpbuf)) deallocate(inpbuf)
751 class default
752 call neko_error('Currently we only read into fld_file_data_t,&
753 please use that data structure instead.&
754 (output_format.adios2)')
755 end select
756
757 end subroutine bp_file_read
758
759#else
760
761 subroutine bp_file_write(this, data, t)
762 class(bp_file_t), intent(inout) :: this
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')
766 end subroutine bp_file_write
767
768 subroutine bp_file_read(this, data)
769 class(bp_file_t) :: this
770 class(*), target, intent(inout) :: data
771 call neko_error('Neko needs to be built with ADIOS2 Fortran support')
772 end subroutine bp_file_read
773
774#endif
775
776 subroutine bp_file_set_precision(this, precision)
777 class(bp_file_t) :: this
778 integer, intent(in) :: precision
779
780 if (precision .eq. dp) then
781 this%dp_precision = .true.
782 else if (precision .eq. sp) then
783 this%dp_precision = .false.
784 else
785 call neko_error('Invalid precision')
786 end if
787
788 end subroutine bp_file_set_precision
789
790 subroutine bp_file_set_layout(this, layout)
791 class(bp_file_t) :: this
792 integer, intent(in) :: layout
793
795 if (layout .ge. 1 .and. layout .le. 3) then
796 this%layout = layout
797 else
798 call neko_error('Invalid data layout')
799 end if
800
801 end subroutine bp_file_set_layout
802
803end module bp_file
double real
ADIOS2 bp file format.
Definition bp_file.F90:36
subroutine bp_file_read(this, data)
Definition bp_file.F90:769
class(buffer_t), allocatable, private outbuf_npar
Definition bp_file.F90:61
class(buffer_t), allocatable, private outbuf_points
Definition bp_file.F90:60
subroutine bp_file_write(this, data, t)
Definition bp_file.F90:762
subroutine bp_file_set_layout(this, layout)
Definition bp_file.F90:791
subroutine bp_file_set_precision(this, precision)
Definition bp_file.F90:777
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:58
integer, public pe_rank
MPI rank.
Definition comm.F90:55
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:42
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:140
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
Definition utils.f90:65
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Definition utils.f90:58
Defines a vector.
Definition vector.f90:34
Interface for ADIOS2 bp files.
Definition bp_file.F90:70
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:63
Pointer to array.
Definition structs.f90:14