Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
re2_file.f90
Go to the documentation of this file.
1! Copyright (c) 2019-2022, The Neko Authors
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!
37 use num_types, only : i8, sp, dp
38 use map_file, only : map_file_t
39 use mesh, only : mesh_t
40 use point, only : point_t
42 use datadist, only : linear_dist_t
43 use map, only : map_t
44 use mesh, only : neko_msh_max_zlbls
45 use logger, only : neko_log, log_size
50 use htable, only : htable_pt_t
51 use comm
52 use mpi_f08
53 implicit none
54 private
55
56 ! Defines the conventions for conversion of re2 labels to labeled zones.
57 integer, public :: neko_w_bc_label = -1
58 integer, public :: neko_v_bc_label = -1
59 integer, public :: neko_o_bc_label = -1
60 integer, public :: neko_sym_bc_label = -1
61 integer, public :: neko_on_bc_label = -1
62 integer, public :: neko_shl_bc_label = -1
63
65 type, public, extends(generic_file_t) :: re2_file_t
66 contains
67 procedure :: read => re2_file_read
68 procedure :: write => re2_file_write
69 end type re2_file_t
70
71contains
72
74 subroutine re2_file_read(this, data)
75 class(re2_file_t) :: this
76 class(*), target, intent(inout) :: data
77 type(mesh_t), pointer :: msh
78 integer :: file_unit
79 character(len=5) :: hdr_ver
80 character(len=54) :: hdr_str
81 character(len=80) :: hdr_full
82 integer :: nel, ndim, nelv, ierr, nBCre2
83 type(mpi_status) :: status
84 type(mpi_file) :: fh
85 integer (kind=MPI_OFFSET_KIND) :: mpi_offset
86 real(kind=sp) :: test
87 real(kind=dp) :: t2
88 integer :: ncurv, nbcs
89 type(linear_dist_t) :: dist
90 type(map_t) :: nm
91 type(map_file_t) :: map_file
92 character(len=1024) :: fname, map_fname
93 logical :: read_map
94 integer :: re2_data_xy_size
95 integer :: re2_data_xyz_size
96 integer :: re2_data_cv_size
97 integer :: re2_data_bc_size
98 logical :: v2_format
99 character(len=LOG_SIZE) :: log_buf
100
101 call this%check_exists()
102
103 select type(data)
104 type is (mesh_t)
105 msh => data
106 class default
107 call neko_error('Invalid output data')
108 end select
109
110 v2_format = .false.
111 fname = trim(this%get_fname())
112 open(newunit=file_unit,file=trim(fname), status='old', iostat=ierr)
113 call neko_log%message('Reading binary NEKTON file ' // fname)
114
115 read(file_unit,'(a80)') hdr_full
116 read(hdr_full, '(a5)') hdr_ver
117
118 if (hdr_ver .eq. '#v004') then
119 read(hdr_full, '(a5,i16,i3,i16,i4,a36)') hdr_ver, nel, ndim, nelv, nbcre2, hdr_str
120 v2_format = .true.
121 else if (hdr_ver .eq. '#v002' .or. hdr_ver .eq. '#v003') then
122 read(hdr_full, '(a5,i9,i3,i9,a54)') hdr_ver, nel, ndim, nelv, hdr_str
123 v2_format = .true.
124 else if (hdr_ver .eq. '#v001') then
125 read(hdr_full, '(a5,i9,i3,i9,a54)') hdr_ver, nel, ndim, nelv, hdr_str
126 end if
127
128 if (v2_format) then
129 call mpi_type_size(mpi_re2v2_data_xy, re2_data_xy_size, ierr)
130 call mpi_type_size(mpi_re2v2_data_xyz, re2_data_xyz_size, ierr)
131 call mpi_type_size(mpi_re2v2_data_cv, re2_data_cv_size, ierr)
132 call mpi_type_size(mpi_re2v2_data_bc, re2_data_bc_size, ierr)
133 else
134 call mpi_type_size(mpi_re2v1_data_xy, re2_data_xy_size, ierr)
135 call mpi_type_size(mpi_re2v1_data_xyz, re2_data_xyz_size, ierr)
136 call mpi_type_size(mpi_re2v1_data_cv, re2_data_cv_size, ierr)
137 call mpi_type_size(mpi_re2v1_data_bc, re2_data_bc_size, ierr)
138 end if
139
140 write(log_buf,1) ndim, nelv
1411 format('gdim = ', i1, ', nelements =', i7)
142 call neko_log%message(log_buf)
143 close(file_unit)
144
145 call filename_chsuffix(fname, map_fname,'map')
146
147 inquire(file=map_fname, exist=read_map)
148 if (read_map) then
149 call nm%init(nelv, 2**ndim)
150 call map_file%init(map_fname)
151 call map_file%read(nm)
152 end if
153
154 call mpi_file_open(neko_comm, trim(fname), &
155 mpi_mode_rdonly, mpi_info_null, fh, ierr)
156
157 if (ierr .ne. 0) then
158 call neko_error("Can't open binary NEKTON file ")
159 end if
160 dist = linear_dist_t(nelv, pe_rank, pe_size, neko_comm)
161
162
163 call msh%init(ndim, dist)
164
165 ! Set offset (header)
166 mpi_offset = re2_hdr_size * mpi_character_size
167
168 call mpi_file_read_at_all(fh, mpi_offset, test, 1, mpi_real, status, ierr)
169 mpi_offset = mpi_offset + mpi_real_size
170
171 if (abs(re2_endian_test - test) .gt. 1e-4) then
172 call neko_error('Invalid endian of re2 file, byte swap not implemented yet')
173 end if
174
175 call re2_file_read_points(msh, ndim, nel, dist, fh, &
176 mpi_offset, re2_data_xy_size, re2_data_xyz_size, v2_format)
177
178
179 ! Set offset to start of curved side data
181 if (ndim .eq. 2) then
182 mpi_offset = mpi_offset + int(dist%num_global(),i8) * int(re2_data_xy_size,i8)
183 else
184 mpi_offset = mpi_offset + int(dist%num_global(),i8) * int(re2_data_xyz_size,i8)
185 end if
186
189 if (v2_format) then
190 call mpi_file_read_at_all(fh, mpi_offset, t2, 1, mpi_double_precision, status, ierr)
191 ncurv = int(t2)
192 mpi_offset = mpi_offset + mpi_double_precision_size
193 call re2_file_read_curve(msh, ncurv, dist, fh, mpi_offset, v2_format)
194 mpi_offset = mpi_offset + int(ncurv,i8) * int(re2_data_cv_size,i8)
195 call mpi_file_read_at_all(fh, mpi_offset, t2, 1, mpi_double_precision, status, ierr)
196 nbcs = int(t2)
197 mpi_offset = mpi_offset + mpi_double_precision_size
198
199 call re2_file_read_bcs(msh, nbcs, dist, fh, mpi_offset, v2_format)
200 else
201 call mpi_file_read_at_all(fh, mpi_offset, ncurv, 1, mpi_integer, status, ierr)
202 mpi_offset = mpi_offset + mpi_integer_size
203 call re2_file_read_curve(msh, ncurv, dist, fh, mpi_offset, v2_format)
204 mpi_offset = mpi_offset + int(ncurv,i8) * int(re2_data_cv_size,i8)
205 call mpi_file_read_at_all(fh, mpi_offset, nbcs, 1, mpi_integer, status, ierr)
206 mpi_offset = mpi_offset + mpi_integer_size
207
208 call re2_file_read_bcs(msh, nbcs, dist, fh, mpi_offset, v2_format)
209
210 end if
211
212 call mpi_file_close(fh, ierr)
213 call msh%finalize()
214
215
216 call neko_log%message('Done')
217
218
219 end subroutine re2_file_read
220
221 subroutine re2_file_write(this, data, t)
222 class(re2_file_t), intent(inout) :: this
223 class(*), target, intent(in) :: data
224 real(kind=dp), intent(in), optional :: t
225 type(re2v1_xy_t), allocatable :: re2_data_xy(:)
226 type(re2v1_xyz_t), allocatable :: re2_data_xyz(:)
227 type(mesh_t), pointer :: msh
228 character(len=5), parameter :: RE2_HDR_VER = '#v001'
229 character(len=54), parameter :: RE2_HDR_STR = 'RE2 exported by NEKO'
230 integer :: i, j, ierr, nelgv
231 integer :: file_unit
232 type(mpi_status) :: status
233 type(mpi_file) :: fh
234 integer (kind=MPI_OFFSET_KIND) :: mpi_offset
235 integer :: element_offset
236 integer :: re2_data_xy_size
237 integer :: re2_data_xyz_size
238
239 select type(data)
240 type is (mesh_t)
241 msh => data
242 class default
243 call neko_error('Invalid output data')
244 end select
245
246 call mpi_type_size(mpi_re2v1_data_xy, re2_data_xy_size, ierr)
247 call mpi_type_size(mpi_re2v1_data_xyz, re2_data_xyz_size, ierr)
248 call mpi_reduce(msh%nelv, nelgv, 1, &
249 mpi_integer, mpi_sum, 0, neko_comm, ierr)
250 element_offset = 0
251 call mpi_exscan(msh%nelv, element_offset, 1, &
252 mpi_integer, mpi_sum, neko_comm, ierr)
253
254 call neko_log%message('Writing data as a binary NEKTON file ' // &
255 this%get_fname())
256
257 if (pe_rank .eq. 0) then
258 open(newunit = file_unit, file = trim(this%get_fname()), &
259 status = 'new', iostat = ierr)
260 if (ierr .ne. 0) then
261 call neko_error("Cannot create new file " // trim(this%get_fname()))
262 end if
263 write(file_unit, '(a5,i9,i3,i9,a54)') re2_hdr_ver, nelgv, msh%gdim,&
264 nelgv, re2_hdr_str
265 close(file_unit)
266 end if
267
268 call mpi_barrier(neko_comm, ierr)
269 call mpi_file_open(neko_comm, trim(this%get_fname()), &
270 mpi_mode_wronly + mpi_mode_create, mpi_info_null, fh, ierr)
271 mpi_offset = re2_hdr_size * mpi_character_size
272
273 call mpi_file_write_at(fh, mpi_offset, re2_endian_test, 1, &
274 mpi_real, status, ierr)
275 mpi_offset = mpi_offset + mpi_real_size
276
277 if (msh%gdim .eq. 2) then
278 allocate(re2_data_xy(msh%nelv))
279 do i = 1, msh%nelv
280 re2_data_xy(i)%rgroup = 1.0 ! Not used
281 do j = 1, 4
282 re2_data_xy(i)%x(j) = real(msh%elements(i)%e%pts(j)%p%x(1))
283 re2_data_xy(i)%y(j) = real(msh%elements(i)%e%pts(j)%p%x(2))
284 end do
285 end do
286 mpi_offset = mpi_offset + element_offset * re2_data_xy_size
287 call mpi_file_write_at(fh, mpi_offset, &
288 re2_data_xy, msh%nelv, mpi_re2v1_data_xy, status, ierr)
289
290 deallocate(re2_data_xy)
291
292 else if (msh%gdim .eq. 3) then
293 allocate(re2_data_xyz(msh%nelv))
294 do i = 1, msh%nelv
295 re2_data_xyz(i)%rgroup = 1.0 ! Not used
296 do j = 1, 8
297 re2_data_xyz(i)%x(j) = real(msh%elements(i)%e%pts(j)%p%x(1))
298 re2_data_xyz(i)%y(j) = real(msh%elements(i)%e%pts(j)%p%x(2))
299 re2_data_xyz(i)%z(j) = real(msh%elements(i)%e%pts(j)%p%x(3))
300 end do
301 end do
302 mpi_offset = mpi_offset + element_offset * re2_data_xyz_size
303 call mpi_file_write_at(fh, mpi_offset, &
304 re2_data_xyz, msh%nelv, mpi_re2v1_data_xyz, status, ierr)
305
306 deallocate(re2_data_xyz)
307 else
308 call neko_error("Invalid dimension of mesh")
309 end if
310
311 call mpi_file_close(fh, ierr)
312 call neko_log%message('Done')
313
315
316 end subroutine re2_file_write
317
318 subroutine re2_file_read_points(msh, ndim, nel, dist, fh, &
319 mpi_offset, re2_data_xy_size, re2_data_xyz_size, v2_format)
320 type(mesh_t), intent(inout) :: msh
321 integer (kind=MPI_OFFSET_KIND) :: mpi_offset
322 integer, intent(inout) :: ndim
323 integer, intent(inout) :: nel
324 type(mpi_file), intent(inout) :: fh
325 integer, intent(in) :: re2_data_xy_size
326 integer, intent(in) :: re2_data_xyz_size
327 logical, intent(in) :: v2_format
328 type(linear_dist_t) :: dist
329 integer :: element_offset
330 type(re2v1_xy_t), allocatable :: re2v1_data_xy(:)
331 type(re2v1_xyz_t), allocatable :: re2v1_data_xyz(:)
332 type(re2v2_xy_t), allocatable :: re2v2_data_xy(:)
333 type(re2v2_xyz_t), allocatable :: re2v2_data_xyz(:)
334 type(mpi_status) :: status
335 type(htable_pt_t) :: htp
336 type(point_t) :: p(8)
337 integer :: pt_idx, nelv
338 integer :: i, j, ierr
339
340 nelv = dist%num_local()
341 element_offset = dist%start_idx()
342
343 call htp%init(2*nel, ndim)
344 pt_idx = 0
345 if (ndim .eq. 2) then
346 mpi_offset = mpi_offset + element_offset * re2_data_xy_size
347 if (.not. v2_format) then
348 allocate(re2v1_data_xy(nelv))
349 call mpi_file_read_at_all(fh, mpi_offset, &
350 re2v1_data_xy, nelv, mpi_re2v1_data_xy, status, ierr)
351 do i = 1, nelv
352 do j = 1, 4
353 call p(j)%init(real(re2v1_data_xy(i)%x(j),dp), &
354 real(re2v1_data_xy(i)%y(j),dp), 0.0d0)
355 call re2_file_add_point(htp, p(j), pt_idx)
356 end do
357 if (nelv > 10) then
358 if(mod(i,nelv/10) .eq. 0) write(*,*) i, 'elements read'
359 end if
360 ! swap vertices to keep symmetric vertex numbering in neko
361 call msh%add_element(i, i, p(1), p(2), p(4), p(3))
362 end do
363 deallocate(re2v1_data_xy)
364 else
365 allocate(re2v2_data_xy(nelv))
366 call mpi_file_read_at_all(fh, mpi_offset, &
367 re2v2_data_xy, nelv, mpi_re2v2_data_xy, status, ierr)
368 do i = 1, nelv
369 do j = 1, 4
370 call p(j)%init(re2v2_data_xy(i)%x(j), &
371 re2v2_data_xy(i)%y(j), 0.0d0)
372 call re2_file_add_point(htp, p(j), pt_idx)
373 end do
374 if (nelv > 10) then
375 if(mod(i,nelv/10) .eq. 0) write(*,*) i, 'elements read'
376 end if
377 ! swap vertices to keep symmetric vertex numbering in neko
378 call msh%add_element(i, i, p(1), p(2), p(4), p(3))
379 end do
380 deallocate(re2v2_data_xy)
381 end if
382 else if (ndim .eq. 3) then
383 mpi_offset = mpi_offset + element_offset * re2_data_xyz_size
384 if (.not. v2_format) then
385 allocate(re2v1_data_xyz(nelv))
386 call mpi_file_read_at_all(fh, mpi_offset, &
387 re2v1_data_xyz, nelv, mpi_re2v1_data_xyz, status, ierr)
388 do i = 1, nelv
389 do j = 1, 8
390 call p(j)%init(real(re2v1_data_xyz(i)%x(j),dp), &
391 real(re2v1_data_xyz(i)%y(j),dp),&
392 real(re2v1_data_xyz(i)%z(j),dp))
393 call re2_file_add_point(htp, p(j), pt_idx)
394 end do
395 if (nelv > 100) then
396 if(mod(i,nelv/100) .eq. 0) write(*,*) i, 'elements read'
397 end if
398 ! swap vertices to keep symmetric vertex numbering in neko
399 call msh%add_element(i, i, &
400 p(1), p(2), p(4), p(3), p(5), p(6), p(8), p(7))
401 end do
402 deallocate(re2v1_data_xyz)
403 else
404 allocate(re2v2_data_xyz(nelv))
405 call mpi_file_read_at_all(fh, mpi_offset, &
406 re2v2_data_xyz, nelv, mpi_re2v2_data_xyz, status, ierr)
407 do i = 1, nelv
408 do j = 1, 8
409 call p(j)%init(re2v2_data_xyz(i)%x(j), &
410 re2v2_data_xyz(i)%y(j),&
411 re2v2_data_xyz(i)%z(j))
412 call re2_file_add_point(htp, p(j), pt_idx)
413 end do
414 if (nelv > 100) then
415 if(mod(i,nelv/100) .eq. 0) write(*,*) i, 'elements read'
416 end if
417 ! swap vertices to keep symmetric vertex numbering in neko
418 call msh%add_element(i, i, &
419 p(1), p(2), p(4), p(3), p(5), p(6), p(8), p(7))
420 end do
421 deallocate(re2v2_data_xyz)
422 end if
423 end if
424
425 call htp%free()
426 end subroutine re2_file_read_points
427
428 subroutine re2_file_read_curve(msh, ncurve, dist, fh, mpi_offset, v2_format)
429 type(mesh_t), intent(inout) :: msh
430 integer (kind=MPI_OFFSET_KIND) :: mpi_offset
431 integer, intent(inout) :: ncurve
432 type(linear_dist_t) :: dist
433 type(mpi_file), intent(inout) :: fh
434 logical, intent(in) :: v2_format
435 type(mpi_status) :: status
436 integer :: i, j, l, ierr, el_idx, id
437 type(re2v1_curve_t), allocatable :: re2v1_data_curve(:)
438 type(re2v2_curve_t), allocatable :: re2v2_data_curve(:)
439 real(kind=dp), allocatable :: curve_data(:,:,:)
440 integer, allocatable :: curve_type(:,:)
441 logical, allocatable :: curve_element(:)
442 character(len=1) :: chtemp
443 logical :: curve_skip = .false.
444
445 allocate(curve_data(5,12,msh%nelv))
446 allocate(curve_element(msh%nelv))
447 allocate(curve_type(12,msh%nelv))
448 do i = 1, msh%nelv
449 curve_element(i) = .false.
450 do j = 1, 12
451 curve_type(j,i) = 0
452 do l = 1, 5
453 curve_data(l,j,i) = 0d0
454 end do
455 end do
456 end do
457
458 call neko_log%message('Reading curved data')
459 if (.not. v2_format) then
460 allocate(re2v1_data_curve(ncurve))
461 call mpi_file_read_at_all(fh, mpi_offset, re2v1_data_curve, ncurve, &
462 mpi_re2v1_data_cv, status, ierr)
463 else
464 allocate(re2v2_data_curve(ncurve))
465 call mpi_file_read_at_all(fh, mpi_offset, re2v2_data_curve, ncurve, &
466 mpi_re2v2_data_cv, status, ierr)
467 end if
468 !This can probably be made nicer...
469 do i = 1, ncurve
470 if(v2_format) then
471 el_idx = re2v2_data_curve(i)%elem - dist%start_idx()
472 id = re2v2_data_curve(i)%zone
473 chtemp = re2v2_data_curve(i)%type
474 do j = 1, 5
475 curve_data(j,id, el_idx) = re2v2_data_curve(i)%point(j)
476 enddo
477 else
478 el_idx = re2v1_data_curve(i)%elem - dist%start_idx()
479 id = re2v1_data_curve(i)%zone
480 chtemp = re2v1_data_curve(i)%type
481 do j = 1, 5
482 curve_data(j,id, el_idx) = real(re2v1_data_curve(i)%point(j),dp)
483 enddo
484 end if
485
486 curve_element(el_idx) = .true.
487 !This might need to be extended
488 select case(trim(chtemp))
489 case ('s')
490 curve_type(id,el_idx) = 1
491 call neko_log%warning('curve type s not supported, treating mesh as non-curved')
492 curve_skip = .true.
493 exit
494 case ('e')
495 curve_type(id,el_idx) = 2
496 call neko_log%warning('curve type e not supported, treating mesh as non-curved')
497 curve_skip = .true.
498 exit
499 case ('C')
500 curve_type(id,el_idx) = 3
501 case ('m')
502 curve_type(id,el_idx) = 4
503 case default
504 write(*,*) chtemp, 'curve type not supported yet, treating mesh as non-curved',id, el_idx
505
506 curve_skip = .true.
507 end select
508 end do
509
510 if( v2_format) then
511 deallocate(re2v2_data_curve)
512 else
513 deallocate(re2v1_data_curve)
514 end if
515 if (.not. curve_skip) then
516 do el_idx = 1, msh%nelv
517 if (curve_element(el_idx)) then
518 call msh%mark_curve_element(el_idx, &
519 curve_data(1,1,el_idx), curve_type(1,el_idx))
520 end if
521 end do
522 end if
523
524 deallocate(curve_data)
525 deallocate(curve_element)
526 deallocate(curve_type)
527 end subroutine re2_file_read_curve
528
529
530 subroutine re2_file_read_bcs(msh, nbcs, dist, fh, mpi_offset, v2_format)
531 type(mesh_t), intent(inout) :: msh
532 integer (kind=MPI_OFFSET_KIND) :: mpi_offset
533 integer, intent(inout) :: nbcs
534 type(linear_dist_t) :: dist
535 type(mpi_file), intent(inout) :: fh
536 logical, intent(in) :: v2_format
537 type(mpi_status) :: status
538 integer :: pids(4)
539 integer :: sym_facet, label
540 integer :: p_el_idx, p_facet
541 integer :: i, j, ierr, el_idx
542 integer, parameter, dimension(6) :: facet_map = (/3, 2, 4, 1, 5, 6/)
543 logical :: periodic
544 type(re2v1_bc_t), allocatable :: re2v1_data_bc(:)
545 type(re2v2_bc_t), allocatable :: re2v2_data_bc(:)
546 character(len=LOG_SIZE) :: log_buf
547
548 ! ---- Offsets for conversion from internal zones to labeled zones
549 integer :: user_labeled_zones(NEKO_MSH_MAX_ZLBLS)
550 integer :: labeled_zone_offsets(NEKO_MSH_MAX_ZLBLS)
551 integer :: total_labeled_zone_offset, current_internal_zone
552 total_labeled_zone_offset = 0
553 labeled_zone_offsets = 0
554 user_labeled_zones = 0
555 current_internal_zone = 1
556 ! ----
557
558 call neko_log%message("Reading boundary conditions")
559 if (.not. v2_format) then
560 allocate(re2v1_data_bc(nbcs))
561 call mpi_file_read_at_all(fh, mpi_offset, re2v1_data_bc, nbcs, &
562 mpi_re2v1_data_bc, status, ierr)
563 else
564 allocate(re2v2_data_bc(nbcs))
565 call mpi_file_read_at_all(fh, mpi_offset, re2v2_data_bc, nbcs, &
566 mpi_re2v2_data_bc, status, ierr)
567 end if
568
569 periodic = .false.
570
572 if (v2_format) then ! V2 format
573
574 !
575 ! Search for user labeled zones
576 !
577 do i = 1, nbcs
578
579 el_idx = int(re2v2_data_bc(i)%elem) - dist%start_idx()
580 sym_facet = facet_map(int(re2v2_data_bc(i)%face))
581
582 select case(trim(re2v2_data_bc(i)%type))
583 case ('MSH', 'msh', 'EXO','exo')
584
585 label = int(re2v2_data_bc(i)%bc_data(5))
586
587 if (label .lt. 1 .or. label .gt. neko_msh_max_zlbls) then
588 call neko_error('Invalid label id (valid range [1,...,20])')
589 end if
590
591 if (user_labeled_zones(label) .eq. 0) then
592 write (log_buf, "(A,I2,A)") "Labeled zone ", label, &
593 " found."
594 call neko_log%message(log_buf)
595 user_labeled_zones(label) = 1
596 end if
597
598 call msh%mark_labeled_facet(sym_facet, el_idx, label)
599
600 ! Get the largest label possible in case we need to convert
601 ! re2 labels to labeled zones (see below).
602 total_labeled_zone_offset = max(total_labeled_zone_offset, label)
603
604
605 end select
606 end do
607
608 do i = 1, nbcs
609 el_idx = int(re2v2_data_bc(i)%elem) - dist%start_idx()
610 sym_facet = facet_map(int(re2v2_data_bc(i)%face))
611 select case(trim(re2v2_data_bc(i)%type))
612 case ('MSH', 'msh', 'EXO','exo')
613 !Do nothing, already handled
614 case ('W')
615 if (neko_w_bc_label .eq. -1) then
616 neko_w_bc_label = current_internal_zone
617 current_internal_zone = current_internal_zone + 1
618 end if
619
620 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
621 re2v2_data_bc(i)%type, &
622 neko_w_bc_label, total_labeled_zone_offset, &
623 labeled_zone_offsets(neko_w_bc_label) .eq. 0)
624
625 labeled_zone_offsets(neko_w_bc_label) = 1
626
627 case ('v', 'V')
628 if (neko_v_bc_label .eq. -1) then
629 neko_v_bc_label = current_internal_zone
630 current_internal_zone = current_internal_zone + 1
631 end if
632
633 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
634 re2v2_data_bc(i)%type, &
635 neko_v_bc_label, total_labeled_zone_offset, &
636 labeled_zone_offsets(neko_v_bc_label) .eq. 0)
637
638 labeled_zone_offsets(neko_v_bc_label) = 1
639 case ('O', 'o')
640 if (neko_o_bc_label .eq. -1) then
641 neko_o_bc_label = current_internal_zone
642 current_internal_zone = current_internal_zone + 1
643 end if
644
645 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
646 re2v2_data_bc(i)%type, &
647 neko_o_bc_label, total_labeled_zone_offset, &
648 labeled_zone_offsets(neko_o_bc_label) .eq. 0)
649
650 labeled_zone_offsets(neko_o_bc_label) = 1
651 case ('SYM','sym')
652 if (neko_sym_bc_label .eq. -1) then
653 neko_sym_bc_label = current_internal_zone
654 current_internal_zone = current_internal_zone + 1
655 end if
656
657 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
658 re2v2_data_bc(i)%type, &
659 neko_sym_bc_label, total_labeled_zone_offset, &
660 labeled_zone_offsets(neko_sym_bc_label) .eq. 0)
661
662 labeled_zone_offsets(neko_sym_bc_label) = 1
663 case ('ON', 'on')
664 if (neko_on_bc_label .eq. -1) then
665 neko_on_bc_label = current_internal_zone
666 current_internal_zone = current_internal_zone + 1
667 end if
668
669 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
670 re2v2_data_bc(i)%type, &
671 neko_on_bc_label, total_labeled_zone_offset, &
672 labeled_zone_offsets(neko_on_bc_label) .eq. 0)
673
674 labeled_zone_offsets(neko_on_bc_label) = 1
675 case ('s', 'sl', 'sh', 'shl', 'S', 'SL', 'SH', 'SHL')
676 if (neko_shl_bc_label .eq. -1) then
677 neko_shl_bc_label = current_internal_zone
678 current_internal_zone = current_internal_zone + 1
679 end if
680
681 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
682 re2v2_data_bc(i)%type, &
683 neko_shl_bc_label, total_labeled_zone_offset, &
684 labeled_zone_offsets(neko_shl_bc_label) .eq. 0)
685
686 labeled_zone_offsets(neko_shl_bc_label) = 1
687 case ('P')
688 periodic = .true.
689 p_el_idx = int(re2v2_data_bc(i)%bc_data(1))
690 p_facet = facet_map(int(re2v2_data_bc(i)%bc_data(2)))
691 call msh%get_facet_ids(sym_facet, el_idx, pids)
692 call msh%mark_periodic_facet(sym_facet, el_idx, &
693 p_facet, p_el_idx, pids)
694 case default
695 write (*,*) trim(re2v2_data_bc(i)%type), 'bc type not supported yet'
696 write (*,*) re2v2_data_bc(i)%bc_data
697 end select
698 end do
699
700 !
701 ! Fix periodic condition for shared nodes
702 !
703 if (periodic) then
704 do j = 1, 3
705 do i = 1, nbcs
706 el_idx = re2v2_data_bc(i)%elem - dist%start_idx()
707 sym_facet = facet_map(int(re2v2_data_bc(i)%face))
708 select case(trim(re2v2_data_bc(i)%type))
709 case ('P')
710 p_el_idx = int(re2v2_data_bc(i)%bc_data(1))
711 p_facet = facet_map(int(re2v2_data_bc(i)%bc_data(2)))
712 call msh%create_periodic_ids(sym_facet, el_idx, &
713 p_facet, p_el_idx)
714 end select
715 end do
716 end do
717 end if
718 deallocate(re2v2_data_bc)
719
720 else ! V! format
721
722 !
723 ! Search for user labeled zones
724 !
725 do i = 1, nbcs
726
727 el_idx = re2v1_data_bc(i)%elem - dist%start_idx()
728 sym_facet = facet_map(re2v1_data_bc(i)%face)
729
730 select case(trim(re2v1_data_bc(i)%type))
731 case ('MSH', 'msh', 'EXO','exo')
732
733 label = int(re2v1_data_bc(i)%bc_data(5))
734
735 if (label .lt. 1 .or. label .gt. neko_msh_max_zlbls) then
736 call neko_error('Invalid label id (valid range [1,...,20])')
737 end if
738
739 if (user_labeled_zones(label) .eq. 0) then
740 write (log_buf, "(A,I2,A,I3)") "Labeled zone ", label, &
741 " found."
742 call neko_log%message(log_buf)
743 user_labeled_zones(label) = 1
744 end if
745
746 ! Get the largest label possible in case we need to convert
747 ! re2 labels to labeled zones (see below).
748 total_labeled_zone_offset = max(total_labeled_zone_offset, label)
749
750 call msh%mark_labeled_facet(sym_facet, el_idx, label)
751
752 end select
753 end do
754
755 do i = 1, nbcs
756
757 el_idx = re2v1_data_bc(i)%elem - dist%start_idx()
758 sym_facet = facet_map(re2v1_data_bc(i)%face)
759 select case(trim(re2v1_data_bc(i)%type))
760 case ('MSH', 'msh', 'EXO','exo')
761 !Do nothing, already handled
762 case ('W')
763 if (neko_w_bc_label .eq. -1) then
764 neko_w_bc_label = current_internal_zone
765 current_internal_zone = current_internal_zone + 1
766 end if
767
768 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
769 re2v1_data_bc(i)%type, &
770 neko_w_bc_label, total_labeled_zone_offset, &
771 labeled_zone_offsets(neko_w_bc_label) .eq. 0)
772
773 labeled_zone_offsets(neko_w_bc_label) = 1
774
775 case ('v', 'V')
776 if (neko_v_bc_label .eq. -1) then
777 neko_v_bc_label = current_internal_zone
778 current_internal_zone = current_internal_zone + 1
779 end if
780
781 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
782 re2v1_data_bc(i)%type, &
783 neko_v_bc_label, total_labeled_zone_offset, &
784 labeled_zone_offsets(neko_v_bc_label) .eq. 0)
785
786 labeled_zone_offsets(neko_v_bc_label) = 1
787 case ('O', 'o')
788 if (neko_o_bc_label .eq. -1) then
789 neko_o_bc_label = current_internal_zone
790 current_internal_zone = current_internal_zone + 1
791 end if
792
793 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
794 re2v1_data_bc(i)%type, &
795 neko_o_bc_label, total_labeled_zone_offset, &
796 labeled_zone_offsets(neko_o_bc_label) .eq. 0)
797
798 labeled_zone_offsets(neko_o_bc_label) = 1
799 case ('SYM','sym')
800 if (neko_sym_bc_label .eq. -1) then
801 neko_sym_bc_label = current_internal_zone
802 current_internal_zone = current_internal_zone + 1
803 end if
804
805 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
806 re2v1_data_bc(i)%type, &
807 neko_sym_bc_label, total_labeled_zone_offset, &
808 labeled_zone_offsets(neko_sym_bc_label) .eq. 0)
809
810 labeled_zone_offsets(neko_sym_bc_label) = 1
811 case ('ON', 'on')
812 if (neko_on_bc_label .eq. -1) then
813 neko_on_bc_label = current_internal_zone
814 current_internal_zone = current_internal_zone + 1
815 end if
816
817 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
818 re2v1_data_bc(i)%type, &
819 neko_on_bc_label, total_labeled_zone_offset, &
820 labeled_zone_offsets(neko_on_bc_label) .eq. 0)
821
822 labeled_zone_offsets(neko_on_bc_label) = 1
823 case ('s', 'sl', 'sh', 'shl', 'S', 'SL', 'SH', 'SHL')
824 if (neko_shl_bc_label .eq. -1) then
825 neko_shl_bc_label = current_internal_zone
826 current_internal_zone = current_internal_zone + 1
827 end if
828
829 call re2_file_mark_labeled_bc(msh, el_idx, sym_facet, &
830 re2v1_data_bc(i)%type, &
831 neko_shl_bc_label, total_labeled_zone_offset, &
832 labeled_zone_offsets(neko_shl_bc_label) .eq. 0)
833
834 labeled_zone_offsets(neko_shl_bc_label) = 1
835 case ('P')
836 periodic = .true.
837 p_el_idx = int(re2v1_data_bc(i)%bc_data(1))
838 p_facet = facet_map(int(re2v1_data_bc(i)%bc_data(2)))
839 call msh%get_facet_ids(sym_facet, el_idx, pids)
840 call msh%mark_periodic_facet(sym_facet, el_idx, &
841 p_facet, p_el_idx, pids)
842 case default
843 write (*,*) re2v1_data_bc(i)%type, 'bc type not supported yet'
844 write (*,*) re2v1_data_bc(i)%bc_data
845 end select
846 end do
847
848 !
849 ! Fix periodic condition for shared nodes
850 !
851 if (periodic) then
852 do j = 1, 3
853 do i = 1, nbcs
854 el_idx = re2v1_data_bc(i)%elem - dist%start_idx()
855 sym_facet = facet_map(re2v1_data_bc(i)%face)
856 select case(trim(re2v1_data_bc(i)%type))
857 case ('P')
858 p_el_idx = int(re2v1_data_bc(i)%bc_data(1))
859 p_facet = facet_map(int(re2v1_data_bc(i)%bc_data(2)))
860 call msh%create_periodic_ids(sym_facet, el_idx, &
861 p_facet, p_el_idx)
862 end select
863 end do
864 end do
865 end if
866
867 deallocate(re2v1_data_bc)
868 end if
869
870 end subroutine re2_file_read_bcs
871
882 subroutine re2_file_mark_labeled_bc(msh, el_idx, facet, type, label, offset, print_info)
883 type(mesh_t), intent(inout) :: msh
884 integer, intent(in) :: el_idx
885 integer, intent(in) :: facet
886 character(len=*), intent(in) :: type
887 integer, intent(in) :: label
888 integer, intent(in) :: offset
889 logical, intent(in) :: print_info
890
891 integer :: mark_label
892 character(len=LOG_SIZE) :: log_buf
893
894 mark_label = offset + label
895
896 if (mark_label .lt. 1 .or. mark_label .gt. neko_msh_max_zlbls) then
897 call neko_error("You have reached the maximum amount of allowed labeled&
898 & zones (max allowed: 20). This happened when converting re2 internal labels&
899 & like e.g. 'w', 'V' or 'o' to labeled zones. Please reduce the number of&
900 & labeled zones that you have defined or make sure that they are labeled&
901 & from [1,...,20].")
902 end if
903
904 if (print_info) then
905 write (log_buf, "(A3,A,I2)") trim(type), " => Labeled index ", mark_label
906 call neko_log%message(log_buf)
907 end if
908 call msh%mark_labeled_facet(facet, el_idx, mark_label)
909
910 end subroutine re2_file_mark_labeled_bc
911
912 subroutine re2_file_add_point(htp, p, idx)
913 type(htable_pt_t), intent(inout) :: htp
914 type(point_t), intent(inout) :: p
915 integer, intent(inout) :: idx
916 integer :: tmp
917
918 if (htp%get(p, tmp) .gt. 0) then
919 idx = idx + 1
920 call htp%set(p, idx)
921 call p%set_id(idx)
922 else
923 call p%set_id(tmp)
924 end if
925
926 end subroutine re2_file_add_point
927
928end module re2_file
double real
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
Module for file I/O operations.
Definition file.f90:34
Implements a hash table ADT.
Definition htable.f90:52
Logging routines.
Definition log.f90:34
type(log_t), public neko_log
Global log stream.
Definition log.f90:92
integer, parameter, public log_size
Definition log.f90:46
NEKTON map file.
Definition map_file.f90:35
NEKTON map.
Definition map.f90:3
Defines a mesh.
Definition mesh.f90:34
integer, parameter, public neko_msh_max_zlbls
Max num. zone labels.
Definition mesh.f90:65
MPI derived types.
Definition mpi_types.f90:34
integer, public mpi_double_precision_size
Size of MPI type double precision.
Definition mpi_types.f90:66
type(mpi_datatype), public mpi_re2v2_data_xyz
MPI derived type for 3D NEKTON re2 data.
Definition mpi_types.f90:57
type(mpi_datatype), public mpi_re2v2_data_xy
MPI derived type for 2D NEKTON re2 data.
Definition mpi_types.f90:58
integer, public mpi_character_size
Size of MPI type character.
Definition mpi_types.f90:67
integer, public mpi_real_size
Size of MPI type real.
Definition mpi_types.f90:65
integer, public mpi_integer_size
Size of MPI type integer.
Definition mpi_types.f90:68
type(mpi_datatype), public mpi_re2v1_data_cv
MPI derived type for NEKTON re2 cv data.
Definition mpi_types.f90:54
type(mpi_datatype), public mpi_re2v2_data_cv
MPI derived type for NEKTON re2 cv data.
Definition mpi_types.f90:59
type(mpi_datatype), public mpi_re2v1_data_xy
MPI derived type for 2D NEKTON re2 data.
Definition mpi_types.f90:53
type(mpi_datatype), public mpi_re2v1_data_bc
MPI derived type for NEKTON re2 bc data.
Definition mpi_types.f90:55
type(mpi_datatype), public mpi_re2v2_data_bc
MPI derived type for NEKTON re2 bc data.
Definition mpi_types.f90:60
type(mpi_datatype), public mpi_re2v1_data_xyz
MPI derived type for 3D NEKTON re2 data.
Definition mpi_types.f90:52
integer, parameter, public i8
Definition num_types.f90:7
integer, parameter, public dp
Definition num_types.f90:10
integer, parameter, public sp
Definition num_types.f90:8
Implements a point.
Definition point.f90:35
NEKTON mesh data in re2 format.
Definition re2_file.f90:35
subroutine re2_file_mark_labeled_bc(msh, el_idx, facet, type, label, offset, print_info)
Mark a labeled zone based on an offset.
Definition re2_file.f90:883
subroutine re2_file_read(this, data)
Load a binary NEKTON mesh from a re2 file.
Definition re2_file.f90:75
subroutine re2_file_write(this, data, t)
Definition re2_file.f90:222
integer, public neko_on_bc_label
Definition re2_file.f90:61
integer, public neko_w_bc_label
Definition re2_file.f90:57
integer, public neko_o_bc_label
Definition re2_file.f90:59
subroutine re2_file_read_bcs(msh, nbcs, dist, fh, mpi_offset, v2_format)
Definition re2_file.f90:531
subroutine re2_file_add_point(htp, p, idx)
Definition re2_file.f90:913
integer, public neko_v_bc_label
Definition re2_file.f90:58
integer, public neko_shl_bc_label
Definition re2_file.f90:62
subroutine re2_file_read_curve(msh, ncurve, dist, fh, mpi_offset, v2_format)
Definition re2_file.f90:429
integer, public neko_sym_bc_label
Definition re2_file.f90:60
subroutine re2_file_read_points(msh, ndim, nel, dist, fh, mpi_offset, re2_data_xy_size, re2_data_xyz_size, v2_format)
Definition re2_file.f90:320
NEKTON re2 format.
Definition re2.f90:2
real(kind=sp), parameter re2_endian_test
NEKTION re2 endian test.
Definition re2.f90:10
integer, parameter re2_hdr_size
NEKTON re2 header size.
Definition re2.f90:7
Utilities.
Definition utils.f90:35
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
Definition utils.f90:195
Load-balanced linear distribution .
Definition datadist.f90:50
A generic file handler.
Point based hash table.
Definition htable.f90:132
NEKTON vertex mapping.
Definition map.f90:8
Interface for NEKTON map files.
Definition map_file.f90:45
A point in with coordinates .
Definition point.f90:43
NEKTON re2 bc data (version 1)
Definition re2.f90:39
NEKTON re2 curve data (version 1)
Definition re2.f90:31
NEKTON re2 element data (2d) (version 1)
Definition re2.f90:25
NEKTON re2 element data (3d) (version 1)
Definition re2.f90:18
NEKTON re2 bc data (version 2)
Definition re2.f90:73
NEKTON re2 curve data (version 2)
Definition re2.f90:65
NEKTON re2 element data (2d) (version 2)
Definition re2.f90:59
NEKTON re2 element data (3d) (version 2)
Definition re2.f90:52
Interface for NEKTON re2 files.
Definition re2_file.f90:65
#define max(a, b)
Definition tensor.cu:40