94 real(kind=
rp),
intent(in),
target :: x(:)
95 real(kind=
rp),
intent(in),
target :: y(:)
96 real(kind=
rp),
intent(in),
target :: z(:)
97 integer,
intent(in) :: nelv
98 type(mpi_comm),
intent(in),
optional :: comm
99 type(
space_t),
intent(in),
target :: Xh
100 real(kind=
dp),
intent(in) :: padding
101 integer :: lx, ly, lz, max_pts_per_iter, ierr, i, id1, id2, n, j
102 real(kind=
dp),
allocatable :: rank_xyz_max(:,:), rank_xyz_min(:,:)
103 real(kind=
dp),
allocatable :: max_xyz(:,:), min_xyz(:,:)
106 type(
aabb_t),
allocatable :: local_aabb(:)
107 integer :: start, last, n_box_el, lvl
109 real(kind=
rp) :: time1, time_start
115 this%padding = padding
117 call mpi_comm_rank(this%comm, this%pe_rank, ierr)
118 call mpi_comm_size(this%comm, this%pe_size, ierr)
121 time_start = mpi_wtime()
127 call local_aabb_tree%init(nelv)
129 allocate(local_aabb(nelv))
132 id1 = lx*ly*lz*(i-1)+1
134 call local_aabb(i)%init(
real((/minval(x(id1:id2)), &
135 minval(y(id1:id2)), &
136 minval(z(id1:id2))/),
dp), &
137 real((/maxval(x(id1:id2)), &
138 maxval(y(id1:id2)), &
139 maxval(z(id1:id2))/), dp))
140 call local_aabb_tree%insert_object(local_aabb(i), i)
147 call mpi_allreduce(mpi_in_place, this%pe_box_num, 1, mpi_integer, &
148 mpi_min, this%comm, ierr)
150 this%pe_box_num =
max(this%pe_box_num,2)
151 this%glob_map_size = this%pe_box_num*this%pe_size
154 print *, this%pe_box_num, this%glob_map_size
157 allocate(rank_xyz_max(3,this%glob_map_size))
158 allocate(rank_xyz_min(3,this%glob_map_size))
159 allocate(min_xyz(3,this%pe_box_num))
160 allocate(max_xyz(3,this%pe_box_num))
163 id_lvl = (/local_aabb_tree%get_root_index(), 0/)
164 call traverse_stack%init()
165 call traverse_stack%push(id_lvl)
169 do while (traverse_stack%size() .gt. 0)
170 id_lvl = traverse_stack%pop()
172 node = local_aabb_tree%get_node(id_lvl%x(1))
173 if (2**lvl .eq. this%pe_box_num .or. node%is_leaf())
then
174 min_xyz(:,i) = node%aabb%get_min()
175 max_xyz(:,i) = node%aabb%get_max()
177 else if (2**lvl < this%pe_box_num)
then
179 temp_id_lvl = (/node%get_left_index(), lvl+1/)
180 call traverse_stack%push(temp_id_lvl)
183 temp_id_lvl = (/node%get_right_index(), lvl+1/)
184 call traverse_stack%push(temp_id_lvl)
188 call traverse_stack%free()
191 if (nelv .eq. 0)
then
193 do j = 1, this%pe_box_num
199 do j = i, this%pe_box_num
200 min_xyz(:,j) = [x(1), y(1), z(1)]
201 max_xyz(:,j) = [x(1), y(1), z(1)]
205 call mpi_allgather(max_xyz, 3*this%pe_box_num, mpi_double_precision, &
206 rank_xyz_max, 3*this%pe_box_num, mpi_double_precision, this%comm, ierr)
207 call mpi_allgather(min_xyz, 3*this%pe_box_num, mpi_double_precision, &
208 rank_xyz_min, 3*this%pe_box_num, mpi_double_precision, this%comm, ierr)
209 call mpi_barrier(this%comm)
210 if (
allocated(this%global_aabb))
deallocate(this%global_aabb)
211 allocate(this%global_aabb(this%glob_map_size))
213 do i = 1, this%glob_map_size
214 call this%global_aabb(i)%init(rank_xyz_min(:,i), rank_xyz_max(:,i))
216 call this%global_aabb_tree%build_from_aabb(this%global_aabb,padding)
217 deallocate(local_aabb)
218 deallocate(rank_xyz_max)
219 deallocate(rank_xyz_min)
254 n_points, points_at_pe, n_points_pe)
256 integer,
intent(in) :: n_points
257 real(kind=
rp),
intent(in) :: points(3,n_points)
259 integer,
intent(inout) :: n_points_pe(0:(this%
pe_size-1))
262 integer :: i, j, temp_intent, pe_id, htable_data
263 real(kind=
dp) :: pt_xyz(3)
264 integer,
pointer :: pe_cands(:)
267 do i = 0, this%pe_size-1
268 call points_at_pe(i)%clear()
272 call marked_rank%init(32, htable_data)
273 call pe_candidates%init()
277 call marked_rank%clear()
278 pt_xyz = (/ points(1,i), points(2,i), points(3,i) /)
279 call my_point%init(pt_xyz)
280 call pe_candidates%clear()
281 call this%find(my_point, pe_candidates)
283 pe_cands => pe_candidates%array()
284 do j = 1, pe_candidates%size()
287 if (marked_rank%get(pe_id, htable_data) .ne. 0)
then
288 n_points_pe(pe_id) = n_points_pe(pe_id) + 1
290 call points_at_pe(pe_id)%push(temp_intent)
293 call marked_rank%set(pe_id, htable_data)
297 if (pe_candidates%size() .lt. 1)
then
298 write (*,*)
'Point', points(:,i), &
299 'found to be outside domain, try increasing the padding to find rank candidates.'
302 call marked_rank%free()
303 call pe_candidates%free()