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
891 call mpi_issend(
buffer%array(),
buffer%size(), mpi_integer, &
895 if (this%neigh(src))
then
896 call mpi_wait(recv_req, status, ierr)
897 call mpi_get_count(status, mpi_integer, n_recv, ierr)
899 select type (fmp => this%facet_map)
901 do j = 1, n_recv, n_nodes + 2
902 neigh_el = recv_buffer(j)
903 recv_side = recv_buffer(j+1)
905 edge = (/ recv_buffer(j+2), recv_buffer(j+3) /)
907 facet_data = (/ 0, 0 /)
909 if (fmp%get(edge, facet_data) .eq. 0)
then
910 element = facet_data%x(1) - this%offset_el
913 call this%elements(
element)%e%facet_id(edge2, l)
914 if(edge2 .eq. edge)
then
919 this%facet_neigh(facet,
element) = -neigh_el
920 facet_data%x(2) = -neigh_el
923 call fmp%set(edge, facet_data)
925 call this%ddata%set_shared_el_facet(
element, facet)
927 call this%ddata%set_shared_facet( &
934 do j = 1, n_recv, n_nodes + 2
935 neigh_el = recv_buffer(j)
936 recv_side = recv_buffer(j+1)
938 face%x = (/ recv_buffer(j+2), recv_buffer(j+3), &
939 recv_buffer(j+4), recv_buffer(j+5) /)
942 facet_data%x = (/ 0, 0 /)
945 if (fmp%get(face, facet_data) .eq. 0)
then
947 element = facet_data%x(1) - this%offset_el
949 call this%elements(
element)%e%facet_id(face2, l)
950 if(face2 .eq. face)
then
955 this%facet_neigh(facet,
element) = -neigh_el
956 facet_data%x(2) = -neigh_el
959 call fmp%set(face, facet_data)
961 call this%ddata%set_shared_el_facet(
element, facet)
963 call this%ddata%set_shared_facet( &
972 if (this%neigh(dst))
then
973 call mpi_wait(send_req, mpi_status_ignore, ierr)
979 deallocate(recv_buffer)
994 type(
mesh_t),
intent(inout) :: this
996 integer(i8),
allocatable :: buf(:), body(:)
997 integer(i8),
pointer :: cr_data(:)
998 integer,
allocatable :: gkey(:), gperm(:), rpos(:)
999 integer,
contiguous,
pointer :: neighs(:)
1000 integer :: i, j, k, n, p, owner, num_neigh, nrec, rlen
1001 integer :: pt_glb_idx, pt_loc_idx, src_rank, neigh_el, rk, rp
1007 call cr_buf%init(this%mpts * 4)
1010 pt_glb_idx = this%points(i)%id()
1011 num_neigh = this%point_neigh(i)%size()
1012 if (2 + num_neigh .gt.
size(body))
then
1014 allocate(body(2 + num_neigh))
1016 body(1) = int(pt_glb_idx,
i8)
1018 neighs => this%point_neigh(i)%array()
1020 body(2 + j) = int(neighs(j),
i8)
1022 owner = modulo(pt_glb_idx,
pe_size)
1028 allocate(buf(
max(n, 1)))
1030 cr_data => cr_buf%array()
1031 buf(1:n) = cr_data(1:n)
1049 p = p + 2 + int(buf(p + 1))
1052 allocate(gkey(
max(nrec, 1)), gperm(
max(nrec, 1)), rpos(
max(nrec, 1)))
1058 gkey(nrec) = int(buf(p + 2))
1059 p = p + 2 + int(buf(p + 1))
1061 if (nrec .gt. 0)
call sort(gkey, gperm, nrec)
1063 call cr_buf%init(
max(n, 1))
1065 do while (i .le. nrec)
1068 do while (j .le. nrec)
1069 if (gkey(j) .ne. gkey(i))
exit
1075 if (j - i .gt. 1)
then
1082 buf(rp + 2 : rp + 1 + int(buf(rp + 1))))
1088 deallocate(gkey, gperm, rpos)
1091 if (
allocated(buf))
deallocate(buf)
1092 allocate(buf(
max(n, 1)))
1094 cr_data => cr_buf%array()
1095 buf(1:n) = cr_data(1:n)
1107 rlen = int(buf(p + 1))
1108 pt_glb_idx = int(buf(p + 2))
1109 src_rank = int(buf(p + 3))
1110 pt_loc_idx = this%have_point_glb_idx(pt_glb_idx)
1111 if (pt_loc_idx .gt. 0)
then
1112 this%neigh(src_rank) = .true.
1113 call this%ddata%set_shared_point(pt_loc_idx)
1115 neigh_el = -int(buf(p + 3 + k))
1116 call this%point_neigh(pt_loc_idx)%push(neigh_el)
1122 if (
allocated(buf))
deallocate(buf)
1130 type(
mesh_t),
target,
intent(inout) :: this
1131 integer,
allocatable :: edge_lp(:,:)
1132 logical,
allocatable :: shared_edges(:)
1133 type(
uset_i8_t),
target :: edge_idx, ghost, owner
1136 type(mpi_status) :: status
1137 type(mpi_request) :: send_req, recv_req
1138 integer,
contiguous,
pointer :: p1(:), p2(:), ns_id(:)
1139 integer :: i, j, id, lid, ierr, num_edge_glb, edge_offset, num_edge_loc
1140 integer :: k, l , shared_offset, glb_nshared, n_glb_id
1141 integer(kind=i8) :: C, glb_max, glb_id
1142 integer(kind=i8),
pointer :: glb_ptr
1143 integer(kind=i8),
allocatable :: recv_buff(:)
1145 integer :: max_recv, src, dst, n_recv
1149 allocate(this%ddata%local_to_global_edge(this%meds))
1151 call edge_idx%init(this%meds)
1152 call send_buff%init(this%meds)
1153 call owner%init(this%meds)
1155 call glb_to_loc%init(32, i)
1163 num_edge_glb = 2* this%meds
1164 call mpi_allreduce(mpi_in_place, num_edge_glb, 1, &
1167 glb_max = int(num_edge_glb,
i8)
1169 call non_shared_edges%init(this%meds)
1173 allocate(edge_lp(2, this%meds))
1174 do lid = 1, this%meds
1175 id = this%edge_pts(1, lid)
1176 edge_lp(1, lid) = this%have_point_glb_idx(id)
1177 id = this%edge_pts(2, lid)
1178 edge_lp(2, lid) = this%have_point_glb_idx(id)
1186 allocate(shared_edges(this%meds))
1188 do lid = 1, this%meds
1191 p1 => this%point_neigh(k)%array()
1192 p2 => this%point_neigh(l)%array()
1194 shared_edges(lid) = .false.
1197 do i = 1, this%point_neigh(k)%size()
1198 do j = 1, this%point_neigh(l)%size()
1199 if ((p1(i) .eq. p2(j)) .and. &
1200 (p1(i) .lt. 0) .and. (p2(j) .lt. 0))
then
1201 shared_edges(lid) = .true.
1211 do lid = 1, this%meds
1217 if (shared_edges(id))
then
1218 call this%ddata%set_shared_edge(id)
1219 glb_id = ((int(this%edge_pts(1, id),
i8)) + &
1220 int(this%edge_pts(2, id),
i8)*c) + glb_max
1221 call glb_to_loc%set(glb_id, id)
1222 call edge_idx%add(glb_id)
1223 call owner%add(glb_id)
1224 call send_buff%push(glb_id)
1226 call non_shared_edges%push(id)
1229 deallocate(shared_edges)
1233 num_edge_loc = non_shared_edges%size()
1234 call mpi_exscan(num_edge_loc, edge_offset, 1, &
1236 edge_offset = edge_offset + 1
1239 ns_id => non_shared_edges%array()
1240 do i = 1, non_shared_edges%size()
1241 call this%ddata%set_local_to_global_edge(ns_id(i), edge_offset)
1242 edge_offset = edge_offset + 1
1250 call mpi_allreduce(send_buff%size(), max_recv, 1, &
1253 call ghost%init(send_buff%size())
1255 allocate(recv_buff(max_recv))
1257 do i = 1,
size(this%neigh_order)
1261 if (this%neigh(src))
then
1262 call mpi_irecv(recv_buff, max_recv, mpi_integer8, &
1266 if (this%neigh(dst))
then
1270 select type(sbarray=>send_buff%data)
1271 type is (
integer(i8))
1275 call mpi_issend(sbarray, send_buff%size(), mpi_integer8, &
1280 if (this%neigh(src))
then
1281 call mpi_wait(recv_req, status, ierr)
1282 call mpi_get_count(status, mpi_integer8, n_recv, ierr)
1285 if ((edge_idx%element(recv_buff(j))) .and. (src .lt.
pe_rank))
then
1286 call ghost%add(recv_buff(j))
1287 call owner%remove(recv_buff(j))
1292 if (this%neigh(dst))
then
1293 call mpi_wait(send_req, mpi_status_ignore, ierr)
1299 glb_nshared = num_edge_loc
1300 call mpi_allreduce(mpi_in_place, glb_nshared, 1, &
1304 call mpi_exscan(owner%size(), shared_offset, 1, &
1306 shared_offset = shared_offset + glb_nshared + 1
1309 call send_buff%clear()
1310 call owner%iter_init()
1311 do while (owner%iter_next())
1312 glb_ptr => owner%iter_value()
1313 if (glb_to_loc%get(glb_ptr, id) .eq. 0)
then
1314 call this%ddata%set_local_to_global_edge(id, shared_offset)
1317 call send_buff%push(glb_ptr)
1318 glb_id = int(shared_offset, i8)
1319 call send_buff%push(glb_id)
1321 shared_offset = shared_offset + 1
1330 this%glb_meds = shared_offset -1
1331 call mpi_allreduce(mpi_in_place, this%glb_meds, 1, &
1338 call mpi_allreduce(send_buff%size(), max_recv, 1, &
1341 deallocate(recv_buff)
1342 allocate(recv_buff(max_recv))
1345 do i = 1,
size(this%neigh_order)
1349 if (this%neigh(src))
then
1350 call mpi_irecv(recv_buff, max_recv, mpi_integer8, &
1354 if (this%neigh(dst))
then
1358 select type(sbarray=>send_buff%data)
1359 type is (
integer(i8))
1363 call mpi_issend(sbarray, send_buff%size(), mpi_integer8, &
1368 if (this%neigh(src))
then
1369 call mpi_wait(recv_req, status, ierr)
1370 call mpi_get_count(status, mpi_integer8, n_recv, ierr)
1373 if (ghost%element(recv_buff(j)))
then
1374 if (glb_to_loc%get(recv_buff(j), id) .eq. 0)
then
1375 n_glb_id = int(recv_buff(j + 1 ), 4)
1376 call this%ddata%set_local_to_global_edge(id, n_glb_id)
1384 if (this%neigh(dst))
then
1385 call mpi_wait(send_req, mpi_status_ignore, ierr)
1389 deallocate(recv_buff)
1390 call glb_to_loc%free()
1391 call send_buff%free()
1392 call edge_idx%free()
1393 call non_shared_edges%free()
1401 type(
mesh_t),
target,
intent(inout) :: this
1402 integer,
contiguous,
pointer :: fd(:), ed(:)
1413 type(mpi_status) :: status
1414 type(mpi_request) :: send_req, recv_req
1415 integer,
allocatable :: recv_buff(:)
1416 integer :: non_shared_facets, shared_facets, facet_offset
1417 integer :: id, lid, glb_nshared, shared_offset, owned_facets
1418 integer :: i, j, ierr, max_recv, src, dst, n_recv
1420 shared_facets = this%ddata%shared_facet%size()
1423 if (this%gdim .eq. 2)
then
1424 allocate(this%ddata%local_to_global_facet(this%meds))
1425 call edge_owner%init(this%meds)
1426 call edge_ghost%init(64, i)
1427 non_shared_facets = this%meds - shared_facets
1429 allocate(this%ddata%local_to_global_facet(this%mfcs))
1430 call face_owner%init(this%mfcs)
1431 call face_ghost%init(64, i)
1432 non_shared_facets = this%mfcs - shared_facets
1438 call mpi_exscan(non_shared_facets, facet_offset, 1, &
1440 facet_offset = facet_offset + 1
1443 if (this%gdim .eq. 2)
then
1444 do lid = 1, this%meds
1446 if (.not. this%ddata%shared_facet%element(id))
then
1447 call this%ddata%set_local_to_global_facet(id, facet_offset)
1448 facet_offset = facet_offset + 1
1450 edge%x = this%edge_pts(:, id)
1451 select type(fmp => this%facet_map)
1453 if (fmp%get(edge, facet_data) .eq. 0)
then
1454 if (facet_data%x(2) .lt. 0)
then
1455 if (abs(facet_data%x(2)) .lt. (this%offset_el + 1))
then
1456 call edge_ghost%set(edge, id)
1458 call edge_owner%push(id)
1467 owned_facets = edge_owner%size()
1469 do lid = 1, this%mfcs
1471 if (.not. this%ddata%shared_facet%element(id))
then
1472 call this%ddata%set_local_to_global_facet(id, facet_offset)
1473 facet_offset = facet_offset + 1
1475 face%x = this%face_pts(:, id)
1476 select type(fmp => this%facet_map)
1478 if (fmp%get(face, facet_data) .eq. 0)
then
1479 if (facet_data%x(2) .lt. 0)
then
1480 if (abs(facet_data%x(2)) .lt. (this%offset_el + 1))
then
1481 call face_ghost%set(face, id)
1483 call face_owner%push(id)
1492 owned_facets = face_owner%size()
1496 glb_nshared = non_shared_facets
1497 call mpi_allreduce(mpi_in_place, glb_nshared, 1, &
1501 call mpi_exscan(owned_facets, shared_offset, 1, &
1503 shared_offset = shared_offset + glb_nshared + 1
1505 if (this%gdim .eq. 2)
then
1507 if (owned_facets .gt. 32)
then
1508 call send_buff%init(owned_facets)
1510 call send_buff%init()
1513 ed => edge_owner%array()
1514 do i = 1, edge_owner%size()
1516 call this%ddata%set_local_to_global_facet(id, shared_offset)
1521 call send_buff%push(this%edge_pts(j, id))
1523 call send_buff%push(shared_offset)
1525 shared_offset = shared_offset + 1
1531 if (owned_facets .gt. 32)
then
1532 call send_buff%init(owned_facets)
1534 call send_buff%init()
1537 fd => face_owner%array()
1538 do i = 1, face_owner%size()
1540 call this%ddata%set_local_to_global_facet(id, shared_offset)
1545 call send_buff%push(this%face_pts(j, id))
1547 call send_buff%push(shared_offset)
1549 shared_offset = shared_offset + 1
1557 this%glb_mfcs = shared_offset - 1
1558 call mpi_allreduce(mpi_in_place, this%glb_mfcs, 1, &
1565 call mpi_allreduce(send_buff%size(), max_recv, 1, &
1568 allocate(recv_buff(max_recv))
1571 do i = 1,
size(this%neigh_order)
1575 if (this%neigh(src))
then
1576 call mpi_irecv(recv_buff, max_recv, mpi_integer, &
1580 if (this%neigh(dst))
then
1584 call mpi_issend(send_buff%array(), send_buff%size(), mpi_integer, &
1588 if (this%neigh(src))
then
1589 call mpi_wait(recv_req, status, ierr)
1590 call mpi_get_count(status, mpi_integer, n_recv, ierr)
1592 if (this%gdim .eq. 2)
then
1595 recv_edge = (/recv_buff(j), recv_buff(j+1)/)
1598 if (edge_ghost%get(recv_edge, id) .eq. 0)
then
1599 call this%ddata%set_local_to_global_facet(id, recv_buff(j+2))
1605 recv_face = (/recv_buff(j), recv_buff(j+1), &
1606 recv_buff(j+2), recv_buff(j+3) /)
1609 if (face_ghost%get(recv_face, id) .eq. 0)
then
1610 call this%ddata%set_local_to_global_facet(id, recv_buff(j+4))
1616 if (this%neigh(dst))
then
1617 call mpi_wait(send_req, mpi_status_ignore, ierr)
1622 if (this%gdim .eq. 2)
then
1623 call edge_owner%free()
1624 call edge_ghost%free()
1626 call face_owner%free()
1627 call face_ghost%free()
1630 call send_buff%free()
1631 deallocate(recv_buff)
1638 class(
mesh_t),
target,
intent(inout) :: this
1639 integer,
value :: el, el_glb
1640 type(
point_t),
target,
intent(inout) :: p1, p2, p3, p4
1645 this%lconn = .false.
1648 this%lnumr = .false.
1650 call this%add_point(p1, p(1))
1651 call this%add_point(p2, p(2))
1652 call this%add_point(p3, p(3))
1653 call this%add_point(p4, p(4))
1655 select type (ep => this%elements(el)%e)
1657 call ep%init(el_glb, &
1658 this%points(p(1)), this%points(p(2)), &
1659 this%points(p(3)), this%points(p(4)))
1669 subroutine mesh_add_hex(this, el, el_glb, p1, p2, p3, p4, p5, p6, p7, p8)
1670 class(
mesh_t),
target,
intent(inout) :: this
1671 integer,
value :: el, el_glb
1672 type(
point_t),
target,
intent(inout) :: p1, p2, p3, p4, p5, p6, p7, p8
1678 this%lconn = .false.
1681 this%lnumr = .false.
1683 call this%add_point(p1, p(1))
1684 call this%add_point(p2, p(2))
1685 call this%add_point(p3, p(3))
1686 call this%add_point(p4, p(4))
1687 call this%add_point(p5, p(5))
1688 call this%add_point(p6, p(6))
1689 call this%add_point(p7, p(7))
1690 call this%add_point(p8, p(8))
1693 call this%htel%set(el_glb, el)
1695 select type (ep => this%elements(el)%e)
1697 call ep%init(el_glb, &
1698 this%points(p(1)), this%points(p(2)), &
1699 this%points(p(3)), this%points(p(4)), &
1700 this%points(p(5)), this%points(p(6)), &
1701 this%points(p(7)), this%points(p(8)))
1710 class(
mesh_t),
intent(inout) :: this
1711 type(
point_t),
intent(inout) :: p
1712 integer,
intent(inout) :: idx
1717 this%max_pts_id =
max(this%max_pts_id, tmp)
1719 if (tmp .le. 0)
then
1723 if (this%htp%get(tmp, idx) .gt. 0)
then
1724 this%mpts = this%mpts + 1
1725 call this%htp%set(tmp, this%mpts)
1726 this%points(this%mpts) = p
1737 type(
mesh_t),
intent(inout) :: this
1739 integer,
intent(inout) :: head(:)
1740 integer,
intent(inout) :: chain(:)
1741 integer,
intent(out) :: idx
1746 lp = this%have_point_glb_idx(f%x(1))
1752 do while (idx .gt. 0)
1753 if ((this%face_pts(2, idx) .eq. f%x(2)) .and. &
1754 (this%face_pts(3, idx) .eq. f%x(3)) .and. &
1755 (this%face_pts(4, idx) .eq. f%x(4)))
return
1759 this%mfcs = this%mfcs + 1
1761 this%face_pts(1, idx) = f%x(1)
1762 this%face_pts(2, idx) = f%x(2)
1763 this%face_pts(3, idx) = f%x(3)
1764 this%face_pts(4, idx) = f%x(4)
1765 chain(idx) = head(lp)
1775 type(
mesh_t),
intent(inout) :: this
1777 integer,
intent(inout) :: head(:)
1778 integer,
intent(inout) :: chain(:)
1779 integer,
intent(out) :: idx
1784 lp = this%have_point_glb_idx(e%x(1))
1790 do while (idx .gt. 0)
1791 if (this%edge_pts(2, idx) .eq. e%x(2))
return
1795 this%meds = this%meds + 1
1797 this%edge_pts(1, idx) = e%x(1)
1798 this%edge_pts(2, idx) = e%x(2)
1799 chain(idx) = head(lp)
1806 class(
mesh_t),
intent(inout) :: this
1807 integer,
intent(in) :: e
1808 real(kind=
dp),
dimension(5,12),
intent(in) :: curve_data
1809 integer,
dimension(12),
intent(in) :: curve_type
1811 if (e .gt. this%nelv)
then
1814 if ((this%gdim .eq. 2 .and. sum(curve_type(5:8)) .gt. 0) )
then
1817 call this%curve%add_element(e, curve_data, curve_type)
1823 class(
mesh_t),
intent(inout) :: this
1824 integer,
intent(in) :: f
1825 integer,
intent(in) :: e
1826 integer,
intent(in) :: label
1828 if (e .gt. this%nelv)
then
1832 if ((this%gdim .eq. 2 .and. f .gt. 4) .or. &
1833 (this%gdim .eq. 3 .and. f .gt. 6))
then
1836 call this%labeled_zones(label)%add_facet(f, e)
1837 this%facet_type(f,e) = -label
1843 class(
mesh_t),
intent(inout) :: this
1844 integer,
intent(in) :: f
1845 integer,
intent(in) :: e
1846 integer,
intent(in) :: pf
1847 integer,
intent(in) :: pe
1848 integer,
intent(inout) :: pids(4)
1849 integer,
dimension(4) :: org_ids
1851 call this%get_facet_ids(f, e, org_ids)
1852 call this%periodic%add_periodic_facet(f, e, pf, pe, pids, org_ids)
1857 class(
mesh_t),
intent(inout) :: this
1858 integer,
intent(in) :: f
1859 integer,
intent(in) :: e
1860 integer,
intent(inout) :: pids(4)
1865 select type(ele => this%elements(e)%e)
1867 call ele%facet_order(t,f)
1870 call ele%facet_order(t2,f)
1880 class(
mesh_t),
intent(inout) :: this
1886 integer :: org_ids(4), pids(4)
1888 integer,
dimension(4, 6) :: face_nodes = reshape([ &
1896 integer,
dimension(2, 4) :: edge_nodes = reshape([ &
1903 do i = 1, this%periodic%size
1904 e = this%periodic%facet_el(i)%x(2)
1905 f = this%periodic%facet_el(i)%x(1)
1906 pe = this%periodic%p_facet_el(i)%x(2)
1907 pf = this%periodic%p_facet_el(i)%x(1)
1908 pids = this%periodic%p_ids(i)%x
1909 call this%get_facet_ids(f, e, pids)
1910 this%periodic%p_ids(i)%x = pids
1912 do i = 1, this%periodic%size
1913 e = this%periodic%facet_el(i)%x(2)
1914 f = this%periodic%facet_el(i)%x(1)
1915 org_ids = this%periodic%org_ids(i)%x
1916 select type(ele => this%elements(e)%e)
1919 pi => ele%pts(face_nodes(j,f))%p
1920 call pi%set_id(org_ids(j))
1924 pi => ele%pts(edge_nodes(j,f))%p
1925 call pi%set_id(org_ids(j))
1933 class(
mesh_t),
intent(inout) :: this
1934 integer,
intent(in) :: f
1935 integer,
intent(in) :: e
1936 integer,
intent(in) :: pf
1937 integer,
intent(in) :: pe
1938 type(
point_t),
pointer :: pi, pj
1939 real(kind=
dp) :: l(3)
1940 integer :: i, j, id, match
1943 integer :: envvar_len
1944 character(len=255) :: tol_str
1945 real(kind=
dp) :: tol
1946 integer,
dimension(4, 6) :: face_nodes = reshape([&
1954 integer,
dimension(2, 4) :: edge_nodes = reshape([&
1961 call get_environment_variable(
"NEKO_PERIODIC_TOL", tol_str, envvar_len)
1962 if (envvar_len .gt. 0)
then
1963 read(tol_str(1:envvar_len), *) tol
1968 select type(ele => this%elements(e)%e)
1970 select type(elp => this%elements(pe)%e)
1974 l = l + ele%pts(face_nodes(i,f))%p%x(1:3) - &
1975 elp%pts(face_nodes(i,pf))%p%x(1:3)
1979 pi => ele%pts(face_nodes(i,f))%p
1982 pj => elp%pts(face_nodes(j,pf))%p
1983 if (norm2(pi%x(1:3) - pj%x(1:3) - l) .lt. tol)
then
1984 id = min(pi%id(), pj%id())
1990 if ( match .gt. 1)
then
1991 call neko_error(
'Multiple matches when creating periodic ids')
1992 else if (match .eq. 0)
then
1993 call neko_error(
'Cannot find matching periodic point')
1998 select type(elp => this%elements(pe)%e)
2002 l = l + ele%pts(edge_nodes(i,f))%p%x(1:3) - &
2003 elp%pts(edge_nodes(i,pf))%p%x(1:3)
2007 pi => ele%pts(edge_nodes(i,f))%p
2009 pj => elp%pts(edge_nodes(j,pf))%p
2011 if (norm2(pi%x(1:3) - pj%x(1:3) - l) .lt. tol)
then
2012 id = min(pi%id(), pj%id())
2025 class(
mesh_t),
intent(inout) :: this
2026 integer,
intent(in) :: f
2027 integer,
intent(in) :: e
2028 integer,
intent(in) :: pf
2029 integer,
intent(in) :: pe
2030 integer,
intent(inout) :: pids(4)
2035 integer,
dimension(4, 6) :: face_nodes = reshape([&
2043 select type(ele => this%elements(e)%e)
2046 pi => ele%pts(face_nodes(i,f))%p
2047 call pi%set_id(pids(i))
2051 if (
allocated(this%htp))
then
2052 call this%add_point(pi, id)
2061 class(
mesh_t),
intent(in) :: this
2062 integer,
intent(in) :: el
2063 integer,
intent(in) :: e
2064 integer :: global_id
2066 global_id = this%edge_lid(e, el)
2068 if (this%gdim .eq. 2)
then
2070 global_id = this%ddata%local_to_global_facet(global_id)
2074 global_id = this%ddata%local_to_global_edge(global_id)
2084 class(
mesh_t),
intent(in) :: this
2085 integer,
intent(in) :: el
2086 integer,
intent(in) :: f
2087 integer :: global_id
2089 global_id = this%face_lid(f, el)
2092 global_id = this%ddata%local_to_global_facet(global_id)
2107 class(
mesh_t),
intent(inout) :: this
2108 integer,
intent(inout) :: index
2111 if (.not.
allocated(this%htp))
then
2112 call neko_error(
'have_point_glb_idx is only valid before generate_conn')
2115 if (this%htp%get(index, local_id) .eq. 1)
then
2124 class(
mesh_t),
intent(inout) :: this
2125 integer,
intent(in) :: el
2126 integer,
intent(in) :: p
2127 integer :: local_index
2130 local_index = this%pt_lid(p, el)
2131 shared = this%ddata%shared_point%element(local_index)
2138 class(
mesh_t),
intent(inout) :: this
2139 integer,
intent(in) :: el
2140 integer,
intent(in) :: e
2141 integer :: local_index
2143 local_index = this%edge_lid(e, el)
2144 if (this%gdim .eq. 2)
then
2145 shared = this%ddata%shared_facet%element(local_index)
2147 shared = this%ddata%shared_edge%element(local_index)
2155 class(
mesh_t),
intent(inout) :: this
2156 integer,
intent(in) :: el
2157 integer,
intent(in) :: f
2158 integer :: local_index
2161 local_index = this%face_lid(f, el)
2162 shared = this%ddata%shared_facet%element(local_index)
2169 class(
mesh_t),
intent(inout) :: this
2171 real(kind=
rp) :: v(8)
2177 if (this%gdim .eq. 3)
then
2180 this%elements(i)%e%pts(2)%p%x, &
2181 this%elements(i)%e%pts(3)%p%x, &
2182 this%elements(i)%e%pts(5)%p%x, &
2183 this%elements(i)%e%pts(1)%p%x &
2187 this%elements(i)%e%pts(4)%p%x, &
2188 this%elements(i)%e%pts(1)%p%x, &
2189 this%elements(i)%e%pts(6)%p%x, &
2190 this%elements(i)%e%pts(2)%p%x &
2194 this%elements(i)%e%pts(1)%p%x, &
2195 this%elements(i)%e%pts(4)%p%x, &
2196 this%elements(i)%e%pts(7)%p%x, &
2197 this%elements(i)%e%pts(3)%p%x &
2201 this%elements(i)%e%pts(3)%p%x, &
2202 this%elements(i)%e%pts(2)%p%x, &
2203 this%elements(i)%e%pts(8)%p%x, &
2204 this%elements(i)%e%pts(4)%p%x &
2208 this%elements(i)%e%pts(6)%p%x, &
2209 this%elements(i)%e%pts(7)%p%x, &
2210 this%elements(i)%e%pts(1)%p%x, &
2211 this%elements(i)%e%pts(5)%p%x &
2215 this%elements(i)%e%pts(8)%p%x, &
2216 this%elements(i)%e%pts(5)%p%x, &
2217 this%elements(i)%e%pts(2)%p%x, &
2218 this%elements(i)%e%pts(6)%p%x &
2222 this%elements(i)%e%pts(5)%p%x, &
2223 this%elements(i)%e%pts(8)%p%x, &
2224 this%elements(i)%e%pts(3)%p%x, &
2225 this%elements(i)%e%pts(7)%p%x &
2229 this%elements(i)%e%pts(7)%p%x, &
2230 this%elements(i)%e%pts(6)%p%x, &
2231 this%elements(i)%e%pts(4)%p%x, &
2232 this%elements(i)%e%pts(8)%p%x &
2235 if (v(1) .le. 0.0_rp .or. &
2236 v(2) .le. 0.0_rp .or. &
2237 v(3) .le. 0.0_rp .or. &
2238 v(4) .le. 0.0_rp .or. &
2239 v(5) .le. 0.0_rp .or. &
2240 v(6) .le. 0.0_rp .or. &
2241 v(7) .le. 0.0_rp .or. &
2242 v(8) .le. 0.0_rp )
then
2244 centroid = this%elements(i)%e%centroid()
2246 write(error_unit,
'(A, A, I0, A, 3G12.5)')
"*** ERROR ***: ", &
2247 "Wrong orientation of mesh element ", i, &
2248 " with centroid ", centroid%x
2256 call neko_error(
"Some mesh elements are not right-handed")
2269 real(kind=
dp),
dimension(3),
intent(in) :: p1, p2, p3, origin
2271 real(kind=
dp) :: vp1(3), vp2(3), vp3(3), cross(3)
2277 cross(1) = vp1(2)*vp2(3) - vp2(3)*vp1(2)
2278 cross(2) = vp1(3)*vp2(1) - vp1(1)*vp2(3)
2279 cross(3) = vp1(1)*vp2(2) - vp1(2)*vp2(1)
2281 v = cross(1)*vp3(1) + cross(2)*vp3(2) + cross(3)*vp3(3)
2295 class(
mesh_t),
intent(in) :: this
2296 class(
mesh_t),
intent(inout) :: other
2297 type(
mask_t),
intent(in) :: mask
2298 integer,
intent(in) :: lx, ly, lz
2299 integer :: i, j, k, nelv, lxyz, gdim, e_m, nidx(4), nelv_c, el_c, el, i_m
2307 nelv =
mask%size()/lxyz
2308 call other%init(this%gdim, nelv)
2311 if (other%gdim .eq. 2)
then
2312 call neko_error(
"Subset mesh not implemented for 2d")
2313 else if (other%gdim .eq. 3)
then
2315 i_m = 1 + lxyz * (el - 1)
2326 call p(j)%init(this%elements(e_m)%e%pts(j)%p%x, p_id)
2330 call other%add_element(el, el + other%offset_el, &
2331 p(1), p(2), p(3), p(4), &
2332 p(5), p(6), p(7), p(8))
2341 nelv_c = this%curve%size
2342 if (nelv_c .gt. 0)
then
2346 do while (el .le. nelv .and. el_c .le. nelv_c)
2348 i_m = 1 + lxyz * (el - 1)
2352 if (e_m .lt. this%curve%curve_el(el_c)%el_idx)
then
2355 else if (e_m .gt. this%curve%curve_el(el_c)%el_idx)
then
2359 call other%mark_curve_element(el, &
2360 this%curve%curve_el(el_c)%curve_data, &
2361 this%curve%curve_el(el_c)%curve_type)
2370 call other%finalize()
2372 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.