53 use mpi_f08,
only : mpi_integer, mpi_max, mpi_sum, mpi_in_place, &
54 mpi_allreduce, mpi_exscan, mpi_request, mpi_status, mpi_wait, &
55 mpi_issend, mpi_irecv, mpi_status_ignore, mpi_integer8, &
60 use,
intrinsic :: iso_fortran_env, only : error_unit
91 logical,
allocatable :: dfrmd_el(:)
105 integer,
allocatable :: pt_lid(:,:)
108 integer,
allocatable :: edge_lid(:,:)
113 integer,
allocatable :: face_lid(:,:)
118 integer,
private,
allocatable :: edge_pts(:,:)
123 integer,
private,
allocatable :: face_pts(:,:)
126 integer,
allocatable :: facet_neigh(:,:)
135 logical,
allocatable :: neigh(:)
136 integer,
allocatable :: neigh_order(:)
138 integer(2),
allocatable :: facet_type(:,:)
144 logical :: lconn = .false.
145 logical :: ldist = .false.
146 logical :: lnumr = .false.
147 logical :: lgenc = .true.
149 logical :: is_submesh = .false.
153 procedure(
mesh_deform), pass(msh),
pointer :: apply_deform => null()
180 procedure, pass(this) :: check_right_handedness => &
183 generic :: init => init_nelv, init_dist
185 generic :: add_element => add_quad, add_hex
193 integer,
intent(in) :: lx, ly, lz
194 real(kind=
rp),
intent(inout) :: x(lx, ly, lz, msh%nelv)
195 real(kind=
rp),
intent(inout) :: y(lx, ly, lz, msh%nelv)
196 real(kind=
rp),
intent(inout) :: z(lx, ly, lz, msh%nelv)
207 class(
mesh_t),
intent(inout) :: this
208 integer,
intent(in) :: gdim
209 integer,
intent(in) :: nelv
212 character(len=LOG_SIZE) :: log_buf
225 if (this%nelv < 1)
then
226 write(log_buf,
'(A,I0,A)')
'MPI rank ',
pe_rank,
' has zero elements'
230 call mpi_allreduce(this%nelv, this%glb_nelv, 1, &
234 call mpi_exscan(this%nelv, this%offset_el, 1, &
243 class(
mesh_t),
intent(inout) :: this
244 integer,
intent(in) :: gdim
247 character(len=LOG_SIZE) :: log_buf
255 this%nelv = dist%num_local()
256 if (this%nelv < 1)
then
257 write(log_buf,
'(A,I0,A)')
'MPI rank ',
pe_rank,
' has zero elements'
260 this%glb_nelv = dist%num_global()
261 this%offset_el = dist%start_idx()
269 type(
mesh_t),
intent(inout) :: this
275 allocate(this%elements(this%nelv))
276 allocate(this%dfrmd_el(this%nelv))
277 if (this%gdim .eq. 3)
then
279 allocate(
hex_t::this%elements(i)%e)
285 select type (fmp => this%facet_map)
287 call fmp%init(this%nelv, facet_data)
295 else if (this%gdim .eq. 2)
then
297 allocate(
quad_t::this%elements(i)%e)
302 select type (fmp => this%facet_map)
304 call fmp%init(this%nelv, facet_data)
316 allocate(this%points(this%npts*this%nelv))
321 allocate(this%pt_lid(this%npts, this%nelv))
324 allocate(this%facet_type(2 * this%gdim, this%nelv))
328 call this%htp%init(this%npts*this%nelv, i)
329 call this%htel%init(this%nelv, i)
331 call this%periodic%init(this%nelv)
335 call this%labeled_zones(i)%init(this%nelv)
338 call this%curve%init(this%nelv)
340 call this%ddata%init()
342 allocate(this%neigh(0:
pe_size-1))
353 class(
mesh_t),
intent(inout) :: this
356 if (
allocated(this%htp))
then
360 call this%htel%free()
361 call this%ddata%free()
362 call this%curve%free()
364 if (
allocated(this%pt_lid))
then
365 deallocate(this%pt_lid)
368 if (
allocated(this%edge_lid))
then
369 deallocate(this%edge_lid)
372 if (
allocated(this%face_lid))
then
373 deallocate(this%face_lid)
376 if (
allocated(this%edge_pts))
then
377 deallocate(this%edge_pts)
380 if (
allocated(this%face_pts))
then
381 deallocate(this%face_pts)
384 if (
allocated(this%dfrmd_el))
then
385 deallocate(this%dfrmd_el)
388 if (
allocated(this%elements))
then
390 call this%elements(i)%e%free()
391 deallocate(this%elements(i)%e)
393 deallocate(this%elements)
396 if (
allocated(this%facet_map))
then
397 select type (fmp => this%facet_map)
403 deallocate(this%facet_map)
406 if (
allocated(this%facet_neigh))
then
407 deallocate(this%facet_neigh)
410 if (
allocated(this%point_neigh))
then
411 do i = 1,
size(this%point_neigh)
412 call this%point_neigh(i)%free()
418 if (
allocated(this%facet_type))
then
419 deallocate(this%facet_type)
421 if (
allocated(this%labeled_zones))
then
423 call this%labeled_zones(i)%free()
425 deallocate(this%labeled_zones)
428 if (
allocated(this%neigh))
then
429 deallocate(this%neigh)
432 if (
allocated(this%neigh_order))
then
433 deallocate(this%neigh_order)
436 if (
allocated(this%points))
then
437 deallocate(this%points)
440 call this%periodic%free()
449 class(
mesh_t),
target,
intent(inout) :: this
455 call this%periodic%finalize()
457 call this%labeled_zones(i)%finalize()
459 call this%curve%finalize()
467 type(
mesh_t),
intent(inout) :: this
468 real(kind=
dp) :: u(3), v(3), w(3), temp
472 if (this%gdim .eq. 2)
then
473 this%dfrmd_el(e) = .false.
474 u = this%elements(e)%e%pts(2)%p%x - this%elements(e)%e%pts(1)%p%x
475 v = this%elements(e)%e%pts(3)%p%x - this%elements(e)%e%pts(1)%p%x
476 temp = u(1)*v(1) + u(2)*v(2)
477 if(.not.
abscmp(temp, 0d0)) this%dfrmd_el(e) = .true.
479 this%dfrmd_el(e) = .false.
480 u = this%elements(e)%e%pts(2)%p%x - this%elements(e)%e%pts(1)%p%x
481 v = this%elements(e)%e%pts(3)%p%x - this%elements(e)%e%pts(1)%p%x
482 w = this%elements(e)%e%pts(5)%p%x - this%elements(e)%e%pts(1)%p%x
483 temp = u(1)*v(1) + u(2)*v(2) + u(3)*v(3)
484 if(.not.
abscmp(temp, 0d0)) this%dfrmd_el(e) = .true.
485 temp = u(1)*w(1) + u(2)*w(2) + u(3)*w(3)
486 if(.not.
abscmp(temp, 0d0)) this%dfrmd_el(e) = .true.
487 u = this%elements(e)%e%pts(7)%p%x - this%elements(e)%e%pts(8)%p%x
488 v = this%elements(e)%e%pts(6)%p%x - this%elements(e)%e%pts(8)%p%x
489 w = this%elements(e)%e%pts(4)%p%x - this%elements(e)%e%pts(8)%p%x
490 temp = u(1)*v(1) + u(2)*v(2) + u(3)*v(3)
491 if(.not.
abscmp(temp, 0d0)) this%dfrmd_el(e) = .true.
492 temp = u(1)*w(1) + u(2)*w(2) + u(3)*w(3)
493 if(.not.
abscmp(temp, 0d0)) this%dfrmd_el(e) = .true.
500 class(
mesh_t),
intent(inout) :: this
501 this%dfrmd_el = .true.
506 class(
mesh_t),
target,
intent(inout) :: this
512 integer :: p_local_idx
514 integer :: i, j, k, ierr, el_glb_idx, n_sides, n_nodes, src, dst
516 if (this%lconn)
return
518 if (.not. this%lgenc)
return
525 ep => this%elements(el)%e
527 call this%add_point(ep%pts(i)%p, p_local_idx)
528 this%pt_lid(i, el) = p_local_idx
533 if (
allocated(this%point_neigh))
then
534 deallocate(this%point_neigh)
536 allocate(this%point_neigh(this%mpts))
538 call this%point_neigh(i)%init(
size = 4)
543 id = this%elements(el)%e%id()
545 call this%point_neigh(this%pt_lid(i, el))%push(id)
555 if (this%gdim .eq. 3)
then
560 if (this%gdim .eq. 2)
then
569 call mpi_allreduce(this%max_pts_id, this%glb_mpts, 1, &
579 select type (fmp => this%facet_map)
583 el_glb_idx = i + this%offset_el
585 call this%elements(i)%e%facet_id(edge, j)
588 facet_data%x = [0, 0]
591 if (fmp%get(edge, facet_data) .eq. 0)
then
593 if (facet_data%x(1) .eq. el_glb_idx )
then
594 this%facet_neigh(j, i) = facet_data%x(2)
595 else if( facet_data%x(2) .eq. el_glb_idx)
then
596 this%facet_neigh(j, i) = facet_data%x(1)
598 else if(facet_data%x(1) .gt. el_glb_idx)
then
599 facet_data%x(2) = facet_data%x(1)
600 facet_data%x(1) = el_glb_idx
601 this%facet_neigh(j, i) = facet_data%x(2)
602 call fmp%set(edge, facet_data)
603 else if(facet_data%x(1) .lt. el_glb_idx)
then
604 facet_data%x(2) = el_glb_idx
605 this%facet_neigh(j, i) = facet_data%x(1)
606 call fmp%set(edge, facet_data)
609 facet_data%x(1) = el_glb_idx
610 this%facet_neigh(j, i) = facet_data%x(2)
611 call fmp%set(edge, facet_data)
620 el_glb_idx = i + this%offset_el
622 call this%elements(i)%e%facet_id(face, j)
624 facet_data%x = (/ 0, 0/)
627 if (fmp%get(face, facet_data) .eq. 0)
then
629 if (facet_data%x(1) .eq. el_glb_idx )
then
630 this%facet_neigh(j, i) = facet_data%x(2)
631 call this%elements(i)%e%facet_id(face_comp, &
632 j + (2*mod(j, 2) - 1))
633 if (face_comp .eq. face)
then
634 facet_data%x(2) = el_glb_idx
635 this%facet_neigh(j, i) = facet_data%x(1)
636 call fmp%set(face, facet_data)
638 else if( facet_data%x(2) .eq. el_glb_idx)
then
639 this%facet_neigh(j, i) = facet_data%x(1)
641 else if(facet_data%x(1) .gt. el_glb_idx)
then
642 facet_data%x(2) = facet_data%x(1)
643 facet_data%x(1) = el_glb_idx
644 this%facet_neigh(j, i) = facet_data%x(2)
645 call fmp%set(face, facet_data)
646 else if(facet_data%x(1) .lt. el_glb_idx)
then
647 facet_data%x(2) = el_glb_idx
648 this%facet_neigh(j, i) = facet_data%x(1)
649 call fmp%set(face, facet_data)
652 facet_data%x(1) = el_glb_idx
653 this%facet_neigh(j, i) = 0
654 call fmp%set(face, facet_data)
679 if (this%neigh(src) .or. this%neigh(dst))
then
681 call neigh_order%push(j)
685 allocate(this%neigh_order(neigh_order%size()))
686 select type(order => neigh_order%data)
688 do i = 1, neigh_order%size()
689 this%neigh_order(i) = order(i)
692 call neigh_order%free()
696 allocate(this%neigh_order(1))
705 if (this%gdim .eq. 3)
then
714 deallocate(this%edge_pts)
715 if (
allocated(this%face_pts))
then
716 deallocate(this%face_pts)
738 type(
mesh_t),
target,
intent(inout) :: this
741 integer,
allocatable :: chain(:), head(:)
742 integer :: el, i, id, n_eds
744 if (this%gdim .eq. 3)
then
750 allocate(this%edge_pts(2, n_eds * this%nelv))
751 allocate(chain(n_eds * this%nelv))
754 allocate(head(this%npts * this%nelv))
759 ep => this%elements(el)%e
763 call ep%edge_id(e, i)
765 this%edge_lid(i, el) = id
769 call ep%facet_id(e, i)
771 this%edge_lid(i, el) = id
790 type(
mesh_t),
target,
intent(inout) :: this
793 integer,
allocatable :: chain(:), head(:)
800 allocate(head(this%npts * this%nelv))
805 ep => this%elements(el)%e
809 call ep%facet_id(f, i)
811 this%face_lid(i, el) = id
823 type(
mesh_t),
intent(inout) :: this
828 type(mpi_status) :: status
829 type(mpi_request) :: send_req, recv_req
830 integer,
allocatable :: recv_buffer(:)
831 integer :: i, j, k, el_glb_idx, n_sides, n_nodes, facet, element, l
832 integer :: max_recv, ierr, src, dst, n_recv, recv_side, neigh_el
835 if (this%gdim .eq. 2)
then
848 el_glb_idx = i + this%offset_el
851 if (this%facet_neigh(j, i) .eq. 0)
then
852 if (n_nodes .eq. 2)
then
853 call this%elements(i)%e%facet_id(edge, j)
854 call buffer%push(el_glb_idx)
857 call buffer%push(edge%x(k))
860 call this%elements(i)%e%facet_id(face, j)
861 call buffer%push(el_glb_idx)
864 call buffer%push(face%x(k))
872 call mpi_allreduce(
buffer%size(), max_recv, 1, &
875 allocate(recv_buffer(max_recv))
877 do i = 1,
size(this%neigh_order)
881 if (this%neigh(src))
then
882 call mpi_irecv(recv_buffer, max_recv, mpi_integer, &
886 if (this%neigh(dst))
then
894 select type (sbarray =>
buffer%data)
896 call mpi_issend(sbarray,
buffer%size(), mpi_integer, &
901 if (this%neigh(src))
then
902 call mpi_wait(recv_req, status, ierr)
903 call mpi_get_count(status, mpi_integer, n_recv, ierr)
905 select type (fmp => this%facet_map)
907 do j = 1, n_recv, n_nodes + 2
908 neigh_el = recv_buffer(j)
909 recv_side = recv_buffer(j+1)
911 edge = (/ recv_buffer(j+2), recv_buffer(j+3) /)
913 facet_data = (/ 0, 0 /)
915 if (fmp%get(edge, facet_data) .eq. 0)
then
916 element = facet_data%x(1) - this%offset_el
919 call this%elements(
element)%e%facet_id(edge2, l)
920 if(edge2 .eq. edge)
then
925 this%facet_neigh(facet,
element) = -neigh_el
926 facet_data%x(2) = -neigh_el
929 call fmp%set(edge, facet_data)
931 call this%ddata%set_shared_el_facet(
element, facet)
933 call this%ddata%set_shared_facet( &
940 do j = 1, n_recv, n_nodes + 2
941 neigh_el = recv_buffer(j)
942 recv_side = recv_buffer(j+1)
944 face%x = (/ recv_buffer(j+2), recv_buffer(j+3), &
945 recv_buffer(j+4), recv_buffer(j+5) /)
948 facet_data%x = (/ 0, 0 /)
951 if (fmp%get(face, facet_data) .eq. 0)
then
953 element = facet_data%x(1) - this%offset_el
955 call this%elements(
element)%e%facet_id(face2, l)
956 if(face2 .eq. face)
then
961 this%facet_neigh(facet,
element) = -neigh_el
962 facet_data%x(2) = -neigh_el
965 call fmp%set(face, facet_data)
967 call this%ddata%set_shared_el_facet(
element, facet)
969 call this%ddata%set_shared_facet( &
978 if (this%neigh(dst))
then
979 call mpi_wait(send_req, mpi_status_ignore, ierr)
985 deallocate(recv_buffer)
1000 type(
mesh_t),
intent(inout) :: this
1002 integer(i8),
allocatable :: buf(:), body(:)
1003 integer(i8),
pointer :: cr_data(:)
1004 integer,
allocatable :: gkey(:), gperm(:), rpos(:)
1005 integer,
contiguous,
pointer :: neighs(:)
1006 integer :: i, j, k, n, p, owner, num_neigh, nrec, rlen
1007 integer :: pt_glb_idx, pt_loc_idx, src_rank, neigh_el, rk, rp
1013 call cr_buf%init(this%mpts * 4)
1016 pt_glb_idx = this%points(i)%id()
1017 num_neigh = this%point_neigh(i)%size()
1018 if (2 + num_neigh .gt.
size(body))
then
1020 allocate(body(2 + num_neigh))
1022 body(1) = int(pt_glb_idx,
i8)
1024 neighs => this%point_neigh(i)%array()
1026 body(2 + j) = int(neighs(j),
i8)
1028 owner = modulo(pt_glb_idx,
pe_size)
1034 allocate(buf(
max(n, 1)))
1036 cr_data => cr_buf%array()
1037 buf(1:n) = cr_data(1:n)
1055 p = p + 2 + int(buf(p + 1))
1058 allocate(gkey(
max(nrec, 1)), gperm(
max(nrec, 1)), rpos(
max(nrec, 1)))
1064 gkey(nrec) = int(buf(p + 2))
1065 p = p + 2 + int(buf(p + 1))
1067 if (nrec .gt. 0)
call sort(gkey, gperm, nrec)
1069 call cr_buf%init(
max(n, 1))
1071 do while (i .le. nrec)
1074 do while (j .le. nrec)
1075 if (gkey(j) .ne. gkey(i))
exit
1081 if (j - i .gt. 1)
then
1088 buf(rp + 2 : rp + 1 + int(buf(rp + 1))))
1094 deallocate(gkey, gperm, rpos)
1097 if (
allocated(buf))
deallocate(buf)
1098 allocate(buf(
max(n, 1)))
1100 cr_data => cr_buf%array()
1101 buf(1:n) = cr_data(1:n)
1113 rlen = int(buf(p + 1))
1114 pt_glb_idx = int(buf(p + 2))
1115 src_rank = int(buf(p + 3))
1116 pt_loc_idx = this%have_point_glb_idx(pt_glb_idx)
1117 if (pt_loc_idx .gt. 0)
then
1118 this%neigh(src_rank) = .true.
1119 call this%ddata%set_shared_point(pt_loc_idx)
1121 neigh_el = -int(buf(p + 3 + k))
1122 call this%point_neigh(pt_loc_idx)%push(neigh_el)
1128 if (
allocated(buf))
deallocate(buf)
1136 type(
mesh_t),
target,
intent(inout) :: this
1137 integer,
allocatable :: edge_lp(:,:)
1138 logical,
allocatable :: shared_edges(:)
1139 type(
uset_i8_t),
target :: edge_idx, ghost, owner
1142 type(mpi_status) :: status
1143 type(mpi_request) :: send_req, recv_req
1144 integer,
contiguous,
pointer :: p1(:), p2(:), ns_id(:)
1145 integer :: i, j, id, lid, ierr, num_edge_glb, edge_offset, num_edge_loc
1146 integer :: k, l , shared_offset, glb_nshared, n_glb_id
1147 integer(kind=i8) :: C, glb_max, glb_id
1148 integer(kind=i8),
pointer :: glb_ptr
1149 integer(kind=i8),
allocatable :: recv_buff(:)
1151 integer :: max_recv, src, dst, n_recv
1155 allocate(this%ddata%local_to_global_edge(this%meds))
1157 call edge_idx%init(this%meds)
1158 call send_buff%init(this%meds)
1159 call owner%init(this%meds)
1161 call glb_to_loc%init(32, i)
1169 num_edge_glb = 2* this%meds
1170 call mpi_allreduce(mpi_in_place, num_edge_glb, 1, &
1173 glb_max = int(num_edge_glb,
i8)
1175 call non_shared_edges%init(this%meds)
1179 allocate(edge_lp(2, this%meds))
1180 do lid = 1, this%meds
1181 id = this%edge_pts(1, lid)
1182 edge_lp(1, lid) = this%have_point_glb_idx(id)
1183 id = this%edge_pts(2, lid)
1184 edge_lp(2, lid) = this%have_point_glb_idx(id)
1192 allocate(shared_edges(this%meds))
1194 do lid = 1, this%meds
1197 p1 => this%point_neigh(k)%array()
1198 p2 => this%point_neigh(l)%array()
1200 shared_edges(lid) = .false.
1203 do i = 1, this%point_neigh(k)%size()
1204 do j = 1, this%point_neigh(l)%size()
1205 if ((p1(i) .eq. p2(j)) .and. &
1206 (p1(i) .lt. 0) .and. (p2(j) .lt. 0))
then
1207 shared_edges(lid) = .true.
1217 do lid = 1, this%meds
1223 if (shared_edges(id))
then
1224 call this%ddata%set_shared_edge(id)
1225 glb_id = ((int(this%edge_pts(1, id),
i8)) + &
1226 int(this%edge_pts(2, id),
i8)*c) + glb_max
1227 call glb_to_loc%set(glb_id, id)
1228 call edge_idx%add(glb_id)
1229 call owner%add(glb_id)
1230 call send_buff%push(glb_id)
1232 call non_shared_edges%push(id)
1235 deallocate(shared_edges)
1239 num_edge_loc = non_shared_edges%size()
1240 call mpi_exscan(num_edge_loc, edge_offset, 1, &
1242 edge_offset = edge_offset + 1
1245 ns_id => non_shared_edges%array()
1246 do i = 1, non_shared_edges%size()
1247 call this%ddata%set_local_to_global_edge(ns_id(i), edge_offset)
1248 edge_offset = edge_offset + 1
1256 call mpi_allreduce(send_buff%size(), max_recv, 1, &
1259 call ghost%init(send_buff%size())
1261 allocate(recv_buff(max_recv))
1263 do i = 1,
size(this%neigh_order)
1267 if (this%neigh(src))
then
1268 call mpi_irecv(recv_buff, max_recv, mpi_integer8, &
1272 if (this%neigh(dst))
then
1276 select type(sbarray=>send_buff%data)
1277 type is (
integer(i8))
1281 call mpi_issend(sbarray, send_buff%size(), mpi_integer8, &
1286 if (this%neigh(src))
then
1287 call mpi_wait(recv_req, status, ierr)
1288 call mpi_get_count(status, mpi_integer8, n_recv, ierr)
1291 if ((edge_idx%element(recv_buff(j))) .and. (src .lt.
pe_rank))
then
1292 call ghost%add(recv_buff(j))
1293 call owner%remove(recv_buff(j))
1298 if (this%neigh(dst))
then
1299 call mpi_wait(send_req, mpi_status_ignore, ierr)
1305 glb_nshared = num_edge_loc
1306 call mpi_allreduce(mpi_in_place, glb_nshared, 1, &
1310 call mpi_exscan(owner%size(), shared_offset, 1, &
1312 shared_offset = shared_offset + glb_nshared + 1
1315 call send_buff%clear()
1316 call owner%iter_init()
1317 do while (owner%iter_next())
1318 glb_ptr => owner%iter_value()
1319 if (glb_to_loc%get(glb_ptr, id) .eq. 0)
then
1320 call this%ddata%set_local_to_global_edge(id, shared_offset)
1323 call send_buff%push(glb_ptr)
1324 glb_id = int(shared_offset, i8)
1325 call send_buff%push(glb_id)
1327 shared_offset = shared_offset + 1
1336 this%glb_meds = shared_offset -1
1337 call mpi_allreduce(mpi_in_place, this%glb_meds, 1, &
1344 call mpi_allreduce(send_buff%size(), max_recv, 1, &
1347 deallocate(recv_buff)
1348 allocate(recv_buff(max_recv))
1351 do i = 1,
size(this%neigh_order)
1355 if (this%neigh(src))
then
1356 call mpi_irecv(recv_buff, max_recv, mpi_integer8, &
1360 if (this%neigh(dst))
then
1364 select type(sbarray=>send_buff%data)
1365 type is (
integer(i8))
1369 call mpi_issend(sbarray, send_buff%size(), mpi_integer8, &
1374 if (this%neigh(src))
then
1375 call mpi_wait(recv_req, status, ierr)
1376 call mpi_get_count(status, mpi_integer8, n_recv, ierr)
1379 if (ghost%element(recv_buff(j)))
then
1380 if (glb_to_loc%get(recv_buff(j), id) .eq. 0)
then
1381 n_glb_id = int(recv_buff(j + 1 ), 4)
1382 call this%ddata%set_local_to_global_edge(id, n_glb_id)
1390 if (this%neigh(dst))
then
1391 call mpi_wait(send_req, mpi_status_ignore, ierr)
1395 deallocate(recv_buff)
1396 call glb_to_loc%free()
1397 call send_buff%free()
1398 call edge_idx%free()
1399 call non_shared_edges%free()
1407 type(
mesh_t),
target,
intent(inout) :: this
1408 integer,
contiguous,
pointer :: fd(:), ed(:)
1419 type(mpi_status) :: status
1420 type(mpi_request) :: send_req, recv_req
1421 integer,
allocatable :: recv_buff(:)
1422 integer :: non_shared_facets, shared_facets, facet_offset
1423 integer :: id, lid, glb_nshared, shared_offset, owned_facets
1424 integer :: i, j, ierr, max_recv, src, dst, n_recv
1426 shared_facets = this%ddata%shared_facet%size()
1429 if (this%gdim .eq. 2)
then
1430 allocate(this%ddata%local_to_global_facet(this%meds))
1431 call edge_owner%init(this%meds)
1432 call edge_ghost%init(64, i)
1433 non_shared_facets = this%meds - shared_facets
1435 allocate(this%ddata%local_to_global_facet(this%mfcs))
1436 call face_owner%init(this%mfcs)
1437 call face_ghost%init(64, i)
1438 non_shared_facets = this%mfcs - shared_facets
1444 call mpi_exscan(non_shared_facets, facet_offset, 1, &
1446 facet_offset = facet_offset + 1
1449 if (this%gdim .eq. 2)
then
1450 do lid = 1, this%meds
1452 if (.not. this%ddata%shared_facet%element(id))
then
1453 call this%ddata%set_local_to_global_facet(id, facet_offset)
1454 facet_offset = facet_offset + 1
1456 edge%x = this%edge_pts(:, id)
1457 select type(fmp => this%facet_map)
1459 if (fmp%get(edge, facet_data) .eq. 0)
then
1460 if (facet_data%x(2) .lt. 0)
then
1461 if (abs(facet_data%x(2)) .lt. (this%offset_el + 1))
then
1462 call edge_ghost%set(edge, id)
1464 call edge_owner%push(id)
1473 owned_facets = edge_owner%size()
1475 do lid = 1, this%mfcs
1477 if (.not. this%ddata%shared_facet%element(id))
then
1478 call this%ddata%set_local_to_global_facet(id, facet_offset)
1479 facet_offset = facet_offset + 1
1481 face%x = this%face_pts(:, id)
1482 select type(fmp => this%facet_map)
1484 if (fmp%get(face, facet_data) .eq. 0)
then
1485 if (facet_data%x(2) .lt. 0)
then
1486 if (abs(facet_data%x(2)) .lt. (this%offset_el + 1))
then
1487 call face_ghost%set(face, id)
1489 call face_owner%push(id)
1498 owned_facets = face_owner%size()
1502 glb_nshared = non_shared_facets
1503 call mpi_allreduce(mpi_in_place, glb_nshared, 1, &
1507 call mpi_exscan(owned_facets, shared_offset, 1, &
1509 shared_offset = shared_offset + glb_nshared + 1
1511 if (this%gdim .eq. 2)
then
1513 if (owned_facets .gt. 32)
then
1514 call send_buff%init(owned_facets)
1516 call send_buff%init()
1519 ed => edge_owner%array()
1520 do i = 1, edge_owner%size()
1522 call this%ddata%set_local_to_global_facet(id, shared_offset)
1527 call send_buff%push(this%edge_pts(j, id))
1529 call send_buff%push(shared_offset)
1531 shared_offset = shared_offset + 1
1537 if (owned_facets .gt. 32)
then
1538 call send_buff%init(owned_facets)
1540 call send_buff%init()
1543 fd => face_owner%array()
1544 do i = 1, face_owner%size()
1546 call this%ddata%set_local_to_global_facet(id, shared_offset)
1551 call send_buff%push(this%face_pts(j, id))
1553 call send_buff%push(shared_offset)
1555 shared_offset = shared_offset + 1
1563 this%glb_mfcs = shared_offset - 1
1564 call mpi_allreduce(mpi_in_place, this%glb_mfcs, 1, &
1571 call mpi_allreduce(send_buff%size(), max_recv, 1, &
1574 allocate(recv_buff(max_recv))
1577 do i = 1,
size(this%neigh_order)
1581 if (this%neigh(src))
then
1582 call mpi_irecv(recv_buff, max_recv, mpi_integer, &
1586 if (this%neigh(dst))
then
1592 select type (sbarray => send_buff%data)
1594 call mpi_issend(sbarray, send_buff%size(), mpi_integer, &
1599 if (this%neigh(src))
then
1600 call mpi_wait(recv_req, status, ierr)
1601 call mpi_get_count(status, mpi_integer, n_recv, ierr)
1603 if (this%gdim .eq. 2)
then
1606 recv_edge = (/recv_buff(j), recv_buff(j+1)/)
1609 if (edge_ghost%get(recv_edge, id) .eq. 0)
then
1610 call this%ddata%set_local_to_global_facet(id, recv_buff(j+2))
1616 recv_face = (/recv_buff(j), recv_buff(j+1), &
1617 recv_buff(j+2), recv_buff(j+3) /)
1620 if (face_ghost%get(recv_face, id) .eq. 0)
then
1621 call this%ddata%set_local_to_global_facet(id, recv_buff(j+4))
1627 if (this%neigh(dst))
then
1628 call mpi_wait(send_req, mpi_status_ignore, ierr)
1633 if (this%gdim .eq. 2)
then
1634 call edge_owner%free()
1635 call edge_ghost%free()
1637 call face_owner%free()
1638 call face_ghost%free()
1641 call send_buff%free()
1642 deallocate(recv_buff)
1649 class(
mesh_t),
target,
intent(inout) :: this
1650 integer,
value :: el, el_glb
1651 type(
point_t),
target,
intent(inout) :: p1, p2, p3, p4
1656 this%lconn = .false.
1659 this%lnumr = .false.
1661 call this%add_point(p1, p(1))
1662 call this%add_point(p2, p(2))
1663 call this%add_point(p3, p(3))
1664 call this%add_point(p4, p(4))
1666 select type (ep => this%elements(el)%e)
1668 call ep%init(el_glb, &
1669 this%points(p(1)), this%points(p(2)), &
1670 this%points(p(3)), this%points(p(4)))
1680 subroutine mesh_add_hex(this, el, el_glb, p1, p2, p3, p4, p5, p6, p7, p8)
1681 class(
mesh_t),
target,
intent(inout) :: this
1682 integer,
value :: el, el_glb
1683 type(
point_t),
target,
intent(inout) :: p1, p2, p3, p4, p5, p6, p7, p8
1689 this%lconn = .false.
1692 this%lnumr = .false.
1694 call this%add_point(p1, p(1))
1695 call this%add_point(p2, p(2))
1696 call this%add_point(p3, p(3))
1697 call this%add_point(p4, p(4))
1698 call this%add_point(p5, p(5))
1699 call this%add_point(p6, p(6))
1700 call this%add_point(p7, p(7))
1701 call this%add_point(p8, p(8))
1704 call this%htel%set(el_glb, el)
1706 select type (ep => this%elements(el)%e)
1708 call ep%init(el_glb, &
1709 this%points(p(1)), this%points(p(2)), &
1710 this%points(p(3)), this%points(p(4)), &
1711 this%points(p(5)), this%points(p(6)), &
1712 this%points(p(7)), this%points(p(8)))
1721 class(
mesh_t),
intent(inout) :: this
1722 type(
point_t),
intent(inout) :: p
1723 integer,
intent(inout) :: idx
1728 this%max_pts_id =
max(this%max_pts_id, tmp)
1730 if (tmp .le. 0)
then
1734 if (this%htp%get(tmp, idx) .gt. 0)
then
1735 this%mpts = this%mpts + 1
1736 call this%htp%set(tmp, this%mpts)
1737 this%points(this%mpts) = p
1748 type(
mesh_t),
intent(inout) :: this
1750 integer,
intent(inout) :: head(:)
1751 integer,
intent(inout) :: chain(:)
1752 integer,
intent(out) :: idx
1757 lp = this%have_point_glb_idx(f%x(1))
1763 do while (idx .gt. 0)
1764 if ((this%face_pts(2, idx) .eq. f%x(2)) .and. &
1765 (this%face_pts(3, idx) .eq. f%x(3)) .and. &
1766 (this%face_pts(4, idx) .eq. f%x(4)))
return
1770 this%mfcs = this%mfcs + 1
1772 this%face_pts(1, idx) = f%x(1)
1773 this%face_pts(2, idx) = f%x(2)
1774 this%face_pts(3, idx) = f%x(3)
1775 this%face_pts(4, idx) = f%x(4)
1776 chain(idx) = head(lp)
1786 type(
mesh_t),
intent(inout) :: this
1788 integer,
intent(inout) :: head(:)
1789 integer,
intent(inout) :: chain(:)
1790 integer,
intent(out) :: idx
1795 lp = this%have_point_glb_idx(e%x(1))
1801 do while (idx .gt. 0)
1802 if (this%edge_pts(2, idx) .eq. e%x(2))
return
1806 this%meds = this%meds + 1
1808 this%edge_pts(1, idx) = e%x(1)
1809 this%edge_pts(2, idx) = e%x(2)
1810 chain(idx) = head(lp)
1817 class(
mesh_t),
intent(inout) :: this
1818 integer,
intent(in) :: e
1819 real(kind=
dp),
dimension(5,12),
intent(in) :: curve_data
1820 integer,
dimension(12),
intent(in) :: curve_type
1822 if (e .gt. this%nelv)
then
1825 if ((this%gdim .eq. 2 .and. sum(curve_type(5:8)) .gt. 0) )
then
1828 call this%curve%add_element(e, curve_data, curve_type)
1834 class(
mesh_t),
intent(inout) :: this
1835 integer,
intent(in) :: f
1836 integer,
intent(in) :: e
1837 integer,
intent(in) :: label
1839 if (e .gt. this%nelv)
then
1843 if ((this%gdim .eq. 2 .and. f .gt. 4) .or. &
1844 (this%gdim .eq. 3 .and. f .gt. 6))
then
1847 call this%labeled_zones(label)%add_facet(f, e)
1848 this%facet_type(f,e) = -label
1854 class(
mesh_t),
intent(inout) :: this
1855 integer,
intent(in) :: f
1856 integer,
intent(in) :: e
1857 integer,
intent(in) :: pf
1858 integer,
intent(in) :: pe
1859 integer,
intent(inout) :: pids(4)
1860 integer,
dimension(4) :: org_ids
1862 call this%get_facet_ids(f, e, org_ids)
1863 call this%periodic%add_periodic_facet(f, e, pf, pe, pids, org_ids)
1868 class(
mesh_t),
intent(inout) :: this
1869 integer,
intent(in) :: f
1870 integer,
intent(in) :: e
1871 integer,
intent(inout) :: pids(4)
1876 select type(ele => this%elements(e)%e)
1878 call ele%facet_order(t,f)
1881 call ele%facet_order(t2,f)
1891 class(
mesh_t),
intent(inout) :: this
1897 integer :: org_ids(4), pids(4)
1899 integer,
dimension(4, 6) :: face_nodes = reshape([ &
1907 integer,
dimension(2, 4) :: edge_nodes = reshape([ &
1914 do i = 1, this%periodic%size
1915 e = this%periodic%facet_el(i)%x(2)
1916 f = this%periodic%facet_el(i)%x(1)
1917 pe = this%periodic%p_facet_el(i)%x(2)
1918 pf = this%periodic%p_facet_el(i)%x(1)
1919 pids = this%periodic%p_ids(i)%x
1920 call this%get_facet_ids(f, e, pids)
1921 this%periodic%p_ids(i)%x = pids
1923 do i = 1, this%periodic%size
1924 e = this%periodic%facet_el(i)%x(2)
1925 f = this%periodic%facet_el(i)%x(1)
1926 org_ids = this%periodic%org_ids(i)%x
1927 select type(ele => this%elements(e)%e)
1930 pi => ele%pts(face_nodes(j,f))%p
1931 call pi%set_id(org_ids(j))
1935 pi => ele%pts(edge_nodes(j,f))%p
1936 call pi%set_id(org_ids(j))
1944 class(
mesh_t),
intent(inout) :: this
1945 integer,
intent(in) :: f
1946 integer,
intent(in) :: e
1947 integer,
intent(in) :: pf
1948 integer,
intent(in) :: pe
1949 type(
point_t),
pointer :: pi, pj
1950 real(kind=
dp) :: l(3)
1951 integer :: i, j, id, match
1954 integer :: envvar_len
1955 character(len=255) :: tol_str
1956 real(kind=
dp) :: tol
1957 integer,
dimension(4, 6) :: face_nodes = reshape([&
1965 integer,
dimension(2, 4) :: edge_nodes = reshape([&
1972 call get_environment_variable(
"NEKO_PERIODIC_TOL", tol_str, envvar_len)
1973 if (envvar_len .gt. 0)
then
1974 read(tol_str(1:envvar_len), *) tol
1979 select type(ele => this%elements(e)%e)
1981 select type(elp => this%elements(pe)%e)
1985 l = l + ele%pts(face_nodes(i,f))%p%x(1:3) - &
1986 elp%pts(face_nodes(i,pf))%p%x(1:3)
1990 pi => ele%pts(face_nodes(i,f))%p
1993 pj => elp%pts(face_nodes(j,pf))%p
1994 if (norm2(pi%x(1:3) - pj%x(1:3) - l) .lt. tol)
then
1995 id = min(pi%id(), pj%id())
2001 if ( match .gt. 1)
then
2002 call neko_error(
'Multiple matches when creating periodic ids')
2003 else if (match .eq. 0)
then
2004 call neko_error(
'Cannot find matching periodic point')
2009 select type(elp => this%elements(pe)%e)
2013 l = l + ele%pts(edge_nodes(i,f))%p%x(1:3) - &
2014 elp%pts(edge_nodes(i,pf))%p%x(1:3)
2018 pi => ele%pts(edge_nodes(i,f))%p
2020 pj => elp%pts(edge_nodes(j,pf))%p
2022 if (norm2(pi%x(1:3) - pj%x(1:3) - l) .lt. tol)
then
2023 id = min(pi%id(), pj%id())
2036 class(
mesh_t),
intent(inout) :: this
2037 integer,
intent(in) :: f
2038 integer,
intent(in) :: e
2039 integer,
intent(in) :: pf
2040 integer,
intent(in) :: pe
2041 integer,
intent(inout) :: pids(4)
2046 integer,
dimension(4, 6) :: face_nodes = reshape([&
2054 select type(ele => this%elements(e)%e)
2057 pi => ele%pts(face_nodes(i,f))%p
2058 call pi%set_id(pids(i))
2062 if (
allocated(this%htp))
then
2063 call this%add_point(pi, id)
2072 class(
mesh_t),
intent(in) :: this
2073 integer,
intent(in) :: el
2074 integer,
intent(in) :: e
2075 integer :: global_id
2077 global_id = this%edge_lid(e, el)
2079 if (this%gdim .eq. 2)
then
2081 global_id = this%ddata%local_to_global_facet(global_id)
2085 global_id = this%ddata%local_to_global_edge(global_id)
2095 class(
mesh_t),
intent(in) :: this
2096 integer,
intent(in) :: el
2097 integer,
intent(in) :: f
2098 integer :: global_id
2100 global_id = this%face_lid(f, el)
2103 global_id = this%ddata%local_to_global_facet(global_id)
2118 class(
mesh_t),
intent(inout) :: this
2119 integer,
intent(inout) :: index
2122 if (.not.
allocated(this%htp))
then
2123 call neko_error(
'have_point_glb_idx is only valid before generate_conn')
2126 if (this%htp%get(index, local_id) .eq. 1)
then
2135 class(
mesh_t),
intent(inout) :: this
2136 integer,
intent(in) :: el
2137 integer,
intent(in) :: p
2138 integer :: local_index
2141 local_index = this%pt_lid(p, el)
2142 shared = this%ddata%shared_point%element(local_index)
2149 class(
mesh_t),
intent(inout) :: this
2150 integer,
intent(in) :: el
2151 integer,
intent(in) :: e
2152 integer :: local_index
2154 local_index = this%edge_lid(e, el)
2155 if (this%gdim .eq. 2)
then
2156 shared = this%ddata%shared_facet%element(local_index)
2158 shared = this%ddata%shared_edge%element(local_index)
2166 class(
mesh_t),
intent(inout) :: this
2167 integer,
intent(in) :: el
2168 integer,
intent(in) :: f
2169 integer :: local_index
2172 local_index = this%face_lid(f, el)
2173 shared = this%ddata%shared_facet%element(local_index)
2180 class(
mesh_t),
intent(inout) :: this
2182 real(kind=
rp) :: v(8)
2188 if (this%gdim .eq. 3)
then
2191 this%elements(i)%e%pts(2)%p%x, &
2192 this%elements(i)%e%pts(3)%p%x, &
2193 this%elements(i)%e%pts(5)%p%x, &
2194 this%elements(i)%e%pts(1)%p%x &
2198 this%elements(i)%e%pts(4)%p%x, &
2199 this%elements(i)%e%pts(1)%p%x, &
2200 this%elements(i)%e%pts(6)%p%x, &
2201 this%elements(i)%e%pts(2)%p%x &
2205 this%elements(i)%e%pts(1)%p%x, &
2206 this%elements(i)%e%pts(4)%p%x, &
2207 this%elements(i)%e%pts(7)%p%x, &
2208 this%elements(i)%e%pts(3)%p%x &
2212 this%elements(i)%e%pts(3)%p%x, &
2213 this%elements(i)%e%pts(2)%p%x, &
2214 this%elements(i)%e%pts(8)%p%x, &
2215 this%elements(i)%e%pts(4)%p%x &
2219 this%elements(i)%e%pts(6)%p%x, &
2220 this%elements(i)%e%pts(7)%p%x, &
2221 this%elements(i)%e%pts(1)%p%x, &
2222 this%elements(i)%e%pts(5)%p%x &
2226 this%elements(i)%e%pts(8)%p%x, &
2227 this%elements(i)%e%pts(5)%p%x, &
2228 this%elements(i)%e%pts(2)%p%x, &
2229 this%elements(i)%e%pts(6)%p%x &
2233 this%elements(i)%e%pts(5)%p%x, &
2234 this%elements(i)%e%pts(8)%p%x, &
2235 this%elements(i)%e%pts(3)%p%x, &
2236 this%elements(i)%e%pts(7)%p%x &
2240 this%elements(i)%e%pts(7)%p%x, &
2241 this%elements(i)%e%pts(6)%p%x, &
2242 this%elements(i)%e%pts(4)%p%x, &
2243 this%elements(i)%e%pts(8)%p%x &
2246 if (v(1) .le. 0.0_rp .or. &
2247 v(2) .le. 0.0_rp .or. &
2248 v(3) .le. 0.0_rp .or. &
2249 v(4) .le. 0.0_rp .or. &
2250 v(5) .le. 0.0_rp .or. &
2251 v(6) .le. 0.0_rp .or. &
2252 v(7) .le. 0.0_rp .or. &
2253 v(8) .le. 0.0_rp )
then
2255 centroid = this%elements(i)%e%centroid()
2257 write(error_unit,
'(A, A, I0, A, 3G12.5)')
"*** ERROR ***: ", &
2258 "Wrong orientation of mesh element ", i, &
2259 " with centroid ", centroid%x
2267 call neko_error(
"Some mesh elements are not right-handed")
2280 real(kind=
dp),
dimension(3),
intent(in) :: p1, p2, p3, origin
2282 real(kind=
dp) :: vp1(3), vp2(3), vp3(3), cross(3)
2288 cross(1) = vp1(2)*vp2(3) - vp2(3)*vp1(2)
2289 cross(2) = vp1(3)*vp2(1) - vp1(1)*vp2(3)
2290 cross(3) = vp1(1)*vp2(2) - vp1(2)*vp2(1)
2292 v = cross(1)*vp3(1) + cross(2)*vp3(2) + cross(3)*vp3(3)
2306 class(
mesh_t),
intent(in) :: this
2307 class(
mesh_t),
intent(inout) :: other
2308 type(
mask_t),
intent(in) :: mask
2309 integer,
intent(in) :: lx, ly, lz
2310 integer :: i, j, k, nelv, lxyz, gdim, e_m, nidx(4), nelv_c, el_c, el, i_m
2318 nelv =
mask%size()/lxyz
2319 call other%init(this%gdim, nelv)
2322 if (other%gdim .eq. 2)
then
2323 call neko_error(
"Subset mesh not implemented for 2d")
2324 else if (other%gdim .eq. 3)
then
2326 i_m = 1 + lxyz * (el - 1)
2337 call p(j)%init(this%elements(e_m)%e%pts(j)%p%x, p_id)
2341 call other%add_element(el, el + other%offset_el, &
2342 p(1), p(2), p(3), p(4), &
2343 p(5), p(6), p(7), p(8))
2352 nelv_c = this%curve%size
2353 if (nelv_c .gt. 0)
then
2357 do while (el .le. nelv .and. el_c .le. nelv_c)
2359 i_m = 1 + lxyz * (el - 1)
2363 if (e_m .lt. this%curve%curve_el(el_c)%el_idx)
then
2366 else if (e_m .gt. this%curve%curve_el(el_c)%el_idx)
then
2370 call other%mark_curve_element(el, &
2371 this%curve%curve_el(el_c)%curve_data, &
2372 this%curve%curve_el(el_c)%curve_type)
2381 call other%finalize()
2383 other%is_submesh = .true.
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Generic buffer that is extended with buffers of varying rank.
integer, public pe_size
MPI size of communicator.
integer, public pe_rank
MPI rank.
type(mpi_comm), public neko_comm
MPI communicator.
Crystal router: scalable all-to-some personalized exchange.
subroutine, public crystal_router_transfer(buf, n)
Route packed records to their destination ranks.
subroutine, public crystal_router_pack(out, dest, body)
Append one record to a packed crystal-router buffer.
Defines a domain as a subset of facets in a mesh.
Defines practical data distributions.
Defines a zone as a subset of facets in a mesh.
Defines a hexahedron element.
integer, parameter, public neko_hex_npts
Number of points.
integer, parameter, public neko_hex_nfcs
Number of faces.
integer, parameter, public neko_hex_neds
Number of edges.
Implements a hash table ADT.
integer, parameter, public log_size
Object for handling masks in Neko.
subroutine mesh_generate_flags(this)
subroutine mesh_add_edge(this, e, head, chain, idx)
Add a unique edge represented as a 2-tuple to the mesh.
subroutine mesh_generate_facet_numbering(this)
Generate a unique facet numbering.
subroutine mesh_init_dist(this, gdim, dist)
Initialise a mesh this based on a distribution dist.
integer, parameter, public neko_msh_max_zlbls
Max num. zone labels.
subroutine mesh_generate_edge_conn(this)
Generate element-element connectivity via edges both between internal and between PEs.
subroutine mesh_add_point(this, p, idx)
Add a unique point to the mesh.
subroutine mesh_free(this)
Deallocate a mesh this.
subroutine mesh_mark_labeled_facet(this, f, e, label)
Mark facet f in element e with label.
subroutine mesh_add_quad(this, el, el_glb, p1, p2, p3, p4)
Add a quadrilateral element to the mesh this.
real(kind=dp) function, public parallelepiped_signed_volume(p1, p2, p3, origin)
Compute a signed volume of a parallelepiped formed by three vectors, in turn defined via three points...
integer, parameter, public neko_msh_max_zlbl_len
Max length of a zone label.
subroutine mesh_mark_periodic_facet(this, f, e, pf, pe, pids)
Mark facet f in element e as periodic with (pf, pe)
subroutine mesh_all_deformed(this)
Set all elements as if they are deformed.
subroutine mesh_generate_edge_lid(this)
Enumerate the unique edges of the local mesh.
subroutine mesh_init_common(this)
subroutine mesh_get_facet_ids(this, f, e, pids)
Get original ids of periodic points.
subroutine mesh_create_periodic_ids(this, f, e, pf, pe)
Creates common ids for matching periodic points.
subroutine mesh_reset_periodic_ids(this)
Reset ids of periodic points to their original ids.
subroutine mesh_add_face(this, f, head, chain, idx)
Add a unique face represented as a 4-tuple to the mesh.
subroutine mesh_init_nelv(this, gdim, nelv)
Initialise a mesh this with nelv elements.
integer function mesh_get_global_edge(this, el, e)
Return the global id of edge e in element el.
integer function mesh_have_point_glb_idx(this, index)
Check if the mesh has a point given its global index.
subroutine mesh_generate_external_point_conn(this)
Generate element-element connectivity via points between PEs.
logical function mesh_is_shared_facet(this, el, f)
Check if facet f in element el is shared.
subroutine mesh_apply_periodic_facet(this, f, e, pf, pe, pids)
Replaces the periodic point's id with a common id for matching periodic points.
subroutine mesh_generate_face_lid(this)
Enumerate the unique faces of the local mesh.
subroutine mesh_finalize(this)
subroutine mesh_generate_external_facet_conn(this)
Generate element-element connectivity via facets between PEs.
subroutine mesh_mark_curve_element(this, e, curve_data, curve_type)
Mark element e as a curve element.
integer function mesh_get_global_facet(this, el, f)
Return the global id of facet f in element el.
subroutine mesh_check_right_handedness(this)
Check the correct orientation of the rst coordindates.
subroutine mesh_generate_conn(this)
Generate element-to-element connectivity.
logical function mesh_is_shared_edge(this, el, e)
Check if edge e in element el is shared.
subroutine mesh_add_hex(this, el, el_glb, p1, p2, p3, p4, p5, p6, p7, p8)
Add a hexahedral element to the mesh this.
subroutine mesh_subset_by_mask(this, other, mask, lx, ly, lz)
Create a subset of the mesh this in other based on the provided mask.
logical function mesh_is_shared_point(this, el, p)
Check if point p in element el is shared.
integer, parameter, public i8
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
Defines a quadrilateral element.
integer, parameter, public neko_quad_neds
Number of edges.
integer, parameter, public neko_quad_npts
Number of points.
Implements a dynamic stack ADT.
Implements an unordered set ADT.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Load-balanced linear distribution .
Base type for an element.
Integer based hash table.
Integer 2-tuple based hash table.
Integer 4-tuple based hash table.
Integer*8 based hash table.
Base type for a hash table.
Type for consistently handling masks in Neko. This type encapsulates the mask array and its associate...
A point in with coordinates .
Integer*8 based unordered set.