47 use mpi_f08,
only: mpi_wtime, mpi_status, mpi_file, mpi_offset_kind, &
48 mpi_mode_wronly, mpi_mode_create, mpi_mode_rdonly, mpi_info_null, &
49 mpi_file_open, mpi_file_close, mpi_file_read_all, mpi_file_write_all, &
50 mpi_file_write_at_all, mpi_file_read_at_all, mpi_integer, mpi_sum, &
51 mpi_exscan, mpi_barrier, mpi_type_size
71 class(*),
target,
intent(inout) :: data
76 type(
mesh_t),
pointer :: msh
77 type(mpi_status) :: status
79 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, mpi_el_offset
80 integer :: i, j, ierr, element_offset
81 integer :: nmsh_quad_size, nmsh_hex_size, nmsh_zone_size
82 integer :: nelv, gdim, nzones, ncurves
86 character(len=LOG_SIZE) :: log_buf
87 real(kind=
rp) :: t_start, t_end
89 call this%check_exists()
100 call neko_log%message(
'Reading a binary Neko file ' // this%fname)
106 call mpi_file_open(
neko_comm, trim(this%fname), &
107 mpi_mode_rdonly, mpi_info_null, fh, ierr)
110 call neko_error(
'Could not open the mesh file ' // this%fname // &
113 call mpi_file_read_all(fh, nelv, 1, mpi_integer, status, ierr)
114 call mpi_file_read_all(fh, gdim, 1, mpi_integer, status, ierr)
116 write(log_buf,1) gdim, nelv
117 1
format(
'gdim = ', i1,
', nelements = ', i9)
120 if (gdim .eq. 2)
then
121 call mpi_file_close(fh, ierr)
126 nelv = dist%num_local()
127 element_offset = dist%start_idx()
129 call msh%init(gdim, nelv)
131 call neko_log%message(
'Reading elements')
133 if (msh%gdim .eq. 2)
then
134 allocate(nmsh_quad(msh%nelv))
136 int(element_offset,
i8) * int(nmsh_quad_size,
i8)
137 call mpi_file_read_at_all(fh, mpi_offset, &
141 p(j) =
point_t(nmsh_quad(i)%v(j)%v_xyz, nmsh_quad(i)%v(j)%v_idx)
144 call msh%add_element(i, p(1), p(2), p(4), p(3))
146 deallocate(nmsh_quad)
148 int(dist%num_global(),
i8) * int(nmsh_quad_size,
i8)
149 else if (msh%gdim .eq. 3)
then
150 allocate(nmsh_hex(msh%nelv))
152 int(element_offset,
i8) * int(nmsh_hex_size,
i8)
153 call mpi_file_read_at_all(fh, mpi_offset, &
157 p(j) =
point_t(nmsh_hex(i)%v(j)%v_xyz, nmsh_hex(i)%v(j)%v_idx)
160 call msh%add_element(i, &
161 p(1), p(2), p(4), p(3), p(5), p(6), p(8), p(7))
165 int(dist%num_global(),
i8) * int(nmsh_hex_size,
i8)
169 call neko_log%message(
'Reading BC/zone data')
171 mpi_offset = mpi_el_offset
172 call mpi_file_read_at_all(fh, mpi_offset, &
173 nzones, 1, mpi_integer, status, ierr)
174 if (nzones .gt. 0)
then
175 allocate(nmsh_zone(nzones))
183 call mpi_file_read_at_all(fh, mpi_offset, &
187 el_idx = nmsh_zone(i)%e
188 if (el_idx .gt. msh%offset_el .and. &
189 el_idx .le. msh%offset_el + msh%nelv)
then
190 el_idx = el_idx - msh%offset_el
191 select case (nmsh_zone(i)%type)
193 call msh%mark_wall_facet(nmsh_zone(i)%f, el_idx)
195 call msh%mark_inlet_facet(nmsh_zone(i)%f, el_idx)
197 call msh%mark_outlet_facet(nmsh_zone(i)%f, el_idx)
199 call msh%mark_sympln_facet(nmsh_zone(i)%f, el_idx)
201 call msh%mark_periodic_facet(nmsh_zone(i)%f, el_idx, &
202 nmsh_zone(i)%p_f, nmsh_zone(i)%p_e, &
203 nmsh_zone(i)%glb_pt_ids)
205 call msh%mark_outlet_normal_facet(nmsh_zone(i)%f, el_idx)
207 call msh%mark_labeled_facet(nmsh_zone(i)%f, el_idx, &
214 el_idx = nmsh_zone(i)%e
215 if (el_idx .gt. msh%offset_el .and. &
216 el_idx .le. msh%offset_el + msh%nelv)
then
217 el_idx = el_idx - msh%offset_el
218 select case (nmsh_zone(i)%type)
220 call msh%apply_periodic_facet(nmsh_zone(i)%f, el_idx, &
221 nmsh_zone(i)%p_f, nmsh_zone(i)%p_e, &
222 nmsh_zone(i)%glb_pt_ids)
227 deallocate(nmsh_zone)
229 call neko_log%message(
'Reading deformation data')
232 int(nzones,
i8)*int(nmsh_zone_size,
i8)
233 call mpi_file_read_at_all(fh, mpi_offset, &
234 ncurves, 1, mpi_integer, status, ierr)
236 if (ncurves .gt. 0)
then
238 allocate(nmsh_curve(ncurves))
240 int(nzones,
i8)*int(nmsh_zone_size,
i8)
241 call mpi_file_read_at_all(fh, mpi_offset, &
245 el_idx = nmsh_curve(i)%e - msh%offset_el
246 if (el_idx .gt. 0 .and. &
247 el_idx .le. msh%nelv)
then
248 call msh%mark_curve_element(el_idx, &
249 nmsh_curve(i)%curve_data, nmsh_curve(i)%type)
254 deallocate(nmsh_curve)
257 call mpi_file_close(fh, ierr)
258 call neko_log%message(
'Mesh read, setting up connectivity')
260 t_start = mpi_wtime()
264 write(log_buf,
'(A)')
'Done setting up mesh and connectivity'
266 write(log_buf,
'(A,F9.6)') &
267 'Mesh and connectivity setup (excluding read) time (s): ', &
279 type(
mesh_t),
pointer,
intent(inout) :: msh
284 type(mpi_status) :: status
286 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, mpi_el_offset
287 integer :: i, j, ierr, element_offset, id
288 integer :: nmsh_quad_size, nmsh_hex_size, nmsh_zone_size
289 integer :: nelv, gdim, nzones, ncurves, ids(4)
293 character(len=LOG_SIZE) :: log_buf
294 real(kind=
rp) :: depth = 1d0
295 real(kind=
dp) :: coord(3)
303 call mpi_file_open(
neko_comm, trim(this%fname), &
304 mpi_mode_rdonly, mpi_info_null, fh, ierr)
305 call mpi_file_read_all(fh, nelv, 1, mpi_integer, status, ierr)
306 call mpi_file_read_all(fh, gdim, 1, mpi_integer, status, ierr)
308 write(log_buf,2) gdim
309 2
format(
'gdim = ', i1,
', no full 2d support, creating thin slab')
314 nelv = dist%num_local()
315 element_offset = dist%start_idx()
317 call msh%init(gdim, nelv)
319 allocate(nmsh_quad(msh%nelv))
321 int(element_offset,
i8) * int(nmsh_quad_size,
i8)
322 call mpi_file_read_at_all(fh, mpi_offset, &
326 coord = nmsh_quad(i)%v(j)%v_xyz
328 p(j) =
point_t(coord, nmsh_quad(i)%v(j)%v_idx)
331 coord = nmsh_quad(i)%v(j)%v_xyz
333 id = nmsh_quad(i)%v(j)%v_idx+msh%glb_nelv*8
337 call msh%add_element(i, &
338 p(1), p(2), p(4), p(3), p(5), p(6), p(8), p(7))
340 deallocate(nmsh_quad)
342 int(dist%num_global(),
i8) * int(nmsh_quad_size,
i8)
344 mpi_offset = mpi_el_offset
345 call mpi_file_read_at_all(fh, mpi_offset, &
346 nzones, 1, mpi_integer, status, ierr)
347 if (nzones .gt. 0)
then
348 allocate(nmsh_zone(nzones))
356 call mpi_file_read_at_all(fh, mpi_offset, &
360 el_idx = nmsh_zone(i)%e
361 if (el_idx .gt. msh%offset_el .and. &
362 el_idx .le. msh%offset_el + msh%nelv)
then
363 el_idx = el_idx - msh%offset_el
364 select case (nmsh_zone(i)%type)
366 call msh%mark_wall_facet(nmsh_zone(i)%f, el_idx)
368 call msh%mark_inlet_facet(nmsh_zone(i)%f, el_idx)
370 call msh%mark_outlet_facet(nmsh_zone(i)%f, el_idx)
372 call msh%mark_sympln_facet(nmsh_zone(i)%f, el_idx)
374 nmsh_zone(i)%glb_pt_ids(3) = nmsh_zone(i)%glb_pt_ids(1) + &
376 nmsh_zone(i)%glb_pt_ids(4) = nmsh_zone(i)%glb_pt_ids(2) + &
378 if (nmsh_zone(i)%f .eq. 1 .or. nmsh_zone(i)%f .eq. 2)
then
379 ids(1) = nmsh_zone(i)%glb_pt_ids(1)
380 ids(2) = nmsh_zone(i)%glb_pt_ids(3)
381 ids(3) = nmsh_zone(i)%glb_pt_ids(4)
382 ids(4) = nmsh_zone(i)%glb_pt_ids(2)
384 ids(1) = nmsh_zone(i)%glb_pt_ids(1)
385 ids(2) = nmsh_zone(i)%glb_pt_ids(2)
386 ids(3) = nmsh_zone(i)%glb_pt_ids(4)
387 ids(4) = nmsh_zone(i)%glb_pt_ids(3)
389 nmsh_zone(i)%glb_pt_ids = ids
390 call msh%mark_periodic_facet(nmsh_zone(i)%f, el_idx, &
391 nmsh_zone(i)%p_f, nmsh_zone(i)%p_e, ids)
393 call msh%mark_outlet_normal_facet(nmsh_zone(i)%f, el_idx)
395 call msh%mark_labeled_facet(nmsh_zone(i)%f, el_idx, &
402 el_idx = nmsh_zone(i)%e
403 if (el_idx .gt. msh%offset_el .and. &
404 el_idx .le. msh%offset_el + msh%nelv)
then
405 el_idx = el_idx - msh%offset_el
406 select case (nmsh_zone(i)%type)
408 call msh%apply_periodic_facet(nmsh_zone(i)%f, el_idx, &
409 nmsh_zone(i)%p_f, nmsh_zone(i)%p_e, &
410 nmsh_zone(i)%glb_pt_ids)
416 call msh%elements(el_idx)%e%facet_order(glb_pt_ids,5)
417 call msh%mark_periodic_facet(6, el_idx, &
418 5, el_idx, glb_pt_ids%x)
419 call msh%elements(el_idx)%e%facet_order(glb_pt_ids,5)
420 call msh%mark_periodic_facet(5, el_idx, &
421 6, el_idx, glb_pt_ids%x)
424 call msh%elements(el_idx)%e%facet_order(glb_pt_ids,5)
425 call msh%apply_periodic_facet(6, el_idx, &
426 5, el_idx, glb_pt_ids%x)
427 call msh%elements(el_idx)%e%facet_order(glb_pt_ids,5)
428 call msh%apply_periodic_facet(5, el_idx, &
429 6, el_idx, glb_pt_ids%x)
432 deallocate(nmsh_zone)
435 mpi_offset = mpi_el_offset + &
437 call mpi_file_read_at_all(fh, mpi_offset, &
438 ncurves, 1, mpi_integer, status, ierr)
440 if (ncurves .gt. 0)
then
442 allocate(nmsh_curve(ncurves))
443 mpi_offset = mpi_el_offset + &
445 int(nzones,
i8)*int(nmsh_zone_size,
i8)
446 call mpi_file_read_at_all(fh, mpi_offset, &
450 el_idx = nmsh_curve(i)%e - msh%offset_el
451 if (el_idx .gt. 0 .and. &
452 el_idx .le. msh%nelv)
then
453 call msh%mark_curve_element(el_idx, &
454 nmsh_curve(i)%curve_data, nmsh_curve(i)%type)
459 deallocate(nmsh_curve)
462 call mpi_file_close(fh, ierr)
474 class(*),
target,
intent(in) :: data
475 real(kind=
rp),
intent(in),
optional :: t
480 type(
mesh_t),
pointer :: msh
481 type(mpi_status) :: status
483 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, mpi_el_offset
484 integer :: i, j, ierr, nelgv, element_offset, k
485 integer :: nmsh_quad_size, nmsh_hex_size, nmsh_zone_size, nmsh_curve_size
486 integer :: nzones, ncurves
488 integer(i4),
dimension(8),
parameter :: vcyc_to_sym = [1, 2, 4, 3, 5, &
503 call mpi_reduce(msh%nelv, nelgv, 1, mpi_integer, &
506 call mpi_exscan(msh%nelv, element_offset, 1, &
509 call neko_log%message(
'Writing data as a binary Neko file ' // this%fname)
511 call mpi_file_open(
neko_comm, trim(this%fname), &
512 mpi_mode_wronly + mpi_mode_create, mpi_info_null, fh, ierr)
514 call mpi_file_write_all(fh, nelgv, 1, mpi_integer, status, ierr)
515 call mpi_file_write_all(fh, msh%gdim, 1, mpi_integer, status, ierr)
517 call msh%reset_periodic_ids()
519 if (msh%gdim .eq. 2)
then
520 allocate(nmsh_quad(msh%nelv))
522 ep => msh%elements(i)%e
523 nmsh_quad(i)%el_idx = ep%id()
525 nmsh_quad(i)%v(j)%v_idx = ep%pts(vcyc_to_sym(j))%p%id()
526 nmsh_quad(i)%v(j)%v_xyz = ep%pts(vcyc_to_sym(j))%p%x
530 int(element_offset,
i8) * int(nmsh_quad_size,
i8)
531 call mpi_file_write_at_all(fh, mpi_offset, &
533 deallocate(nmsh_quad)
535 int(nelgv,
i8) * int(nmsh_quad_size,
i8)
536 else if (msh%gdim .eq. 3)
then
537 allocate(nmsh_hex(msh%nelv))
539 ep => msh%elements(i)%e
540 nmsh_hex(i)%el_idx = ep%id()
542 nmsh_hex(i)%v(j)%v_idx = ep%pts(vcyc_to_sym(j))%p%id()
543 nmsh_hex(i)%v(j)%v_xyz = ep%pts(vcyc_to_sym(j))%p%x
547 int(element_offset,
i8) * int(nmsh_hex_size,
i8)
548 call mpi_file_write_at_all(fh, mpi_offset, &
553 call mpi_file_write_at_all(fh, mpi_offset, &
560 int(nelgv,
i8) * int(nmsh_hex_size,
i8)
565 nzones = msh%wall%size + msh%inlet%size + msh%outlet%size + &
566 msh%sympln%size + msh%periodic%size + msh%outlet_normal%size
569 nzones = nzones + msh%labeled_zones(i)%size
571 mpi_offset = mpi_el_offset
572 call mpi_file_write_at_all(fh, mpi_offset, &
573 nzones, 1, mpi_integer, status, ierr)
575 if (nzones .gt. 0)
then
576 allocate(nmsh_zone(nzones))
578 nmsh_zone(:)%type = 0
581 do i = 1, msh%wall%size
582 nmsh_zone(j)%e = msh%wall%facet_el(i)%x(2) + msh%offset_el
583 nmsh_zone(j)%f = msh%wall%facet_el(i)%x(1)
584 nmsh_zone(j)%type = 1
588 do i = 1, msh%inlet%size
589 nmsh_zone(j)%e = msh%inlet%facet_el(i)%x(2) + msh%offset_el
590 nmsh_zone(j)%f = msh%inlet%facet_el(i)%x(1)
591 nmsh_zone(j)%type = 2
595 do i = 1, msh%outlet%size
596 nmsh_zone(j)%e = msh%outlet%facet_el(i)%x(2) + msh%offset_el
597 nmsh_zone(j)%f = msh%outlet%facet_el(i)%x(1)
598 nmsh_zone(j)%type = 3
602 do i = 1, msh%sympln%size
603 nmsh_zone(j)%e = msh%sympln%facet_el(i)%x(2) + msh%offset_el
604 nmsh_zone(j)%f = msh%sympln%facet_el(i)%x(1)
605 nmsh_zone(j)%type = 4
609 do i = 1, msh%periodic%size
610 nmsh_zone(j)%e = msh%periodic%facet_el(i)%x(2) + msh%offset_el
611 nmsh_zone(j)%f = msh%periodic%facet_el(i)%x(1)
612 nmsh_zone(j)%p_e = msh%periodic%p_facet_el(i)%x(2)
613 nmsh_zone(j)%p_f = msh%periodic%p_facet_el(i)%x(1)
614 nmsh_zone(j)%glb_pt_ids = msh%periodic%p_ids(i)%x
615 nmsh_zone(j)%type = 5
618 do i = 1, msh%outlet_normal%size
619 nmsh_zone(j)%e = msh%outlet_normal%facet_el(i)%x(2) + msh%offset_el
620 nmsh_zone(j)%f = msh%outlet_normal%facet_el(i)%x(1)
621 nmsh_zone(j)%type = 6
625 do i = 1, msh%labeled_zones(k)%size
626 nmsh_zone(j)%e = msh%labeled_zones(k)%facet_el(i)%x(2) + &
628 nmsh_zone(j)%f = msh%labeled_zones(k)%facet_el(i)%x(1)
630 nmsh_zone(j)%type = 7
637 call mpi_file_write_at_all(fh, mpi_offset, &
640 deallocate(nmsh_zone)
643 ncurves = msh%curve%size
645 int(nzones,
i8)*int(nmsh_zone_size,
i8)
647 call mpi_file_write_at_all(fh, mpi_offset, &
648 ncurves, 1, mpi_integer, status, ierr)
650 if (ncurves .gt. 0)
then
651 allocate(nmsh_curve(ncurves))
653 nmsh_curve(i)%type = 0
657 nmsh_curve(i)%e = msh%curve%curve_el(i)%el_idx + msh%offset_el
658 nmsh_curve(i)%curve_data = msh%curve%curve_el(i)%curve_data
659 nmsh_curve(i)%type = msh%curve%curve_el(i)%curve_type
662 int(nzones,
i8)*int(nmsh_zone_size,
i8)
663 call mpi_file_write_at_all(fh, mpi_offset, &
666 deallocate(nmsh_curve)
669 call mpi_file_sync(fh, ierr)
670 call mpi_file_close(fh, ierr)
type(mpi_comm) neko_comm
MPI communicator.
integer pe_size
MPI size of communicator.
Defines practical data distributions.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
integer, parameter, public neko_msh_max_zlbls
Max num. zone labels.
type(mpi_datatype), public mpi_nmsh_hex
MPI derived type for 3D Neko nmsh data.
type(mpi_datatype), public mpi_nmsh_quad
MPI derived type for 2D Neko nmsh data.
type(mpi_datatype), public mpi_nmsh_curve
MPI derived type for Neko nmsh curved elements.
integer, public mpi_integer_size
Size of MPI type integer.
type(mpi_datatype), public mpi_nmsh_zone
MPI derived type for Neko nmsh zone data.
subroutine nmsh_file_write(this, data, t)
Write a mesh from to a binary Neko nmsh file.
subroutine nmsh_file_read(this, data)
Load a mesh from a binary Neko nmsh file.
integer, parameter max_write_nel
Specifices the maximum number of elements any rank is allowed to write (for nmsh)....
subroutine nmsh_file_read_2d(this, msh)
Load a mesh from a binary Neko nmsh file.
integer, parameter, public i8
integer, parameter, public i4
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
Load-balanced linear distribution .
Base type for an element.
Interface for Neko nmsh files.
A point in with coordinates .