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