74 type(
coef_t),
intent(inout),
target :: coef
75 integer,
intent(in) :: dir
76 real(kind=
rp),
intent(in) :: tol
77 integer :: nelv, lx, n, i, e, lvl, ierr
78 real(kind=
rp),
contiguous,
pointer :: line(:, :, :, :)
79 real(kind=
rp),
allocatable :: min_vals(:, :, :, :)
80 real(kind=
rp),
allocatable :: min_temp(:, :, :, :)
81 type(c_ptr) :: min_vals_d = c_null_ptr
82 real(kind=
rp) :: el_dim(3, 3), glb_min, glb_max, el_min
88 call neko_warning(
'map_1d does not copy indices to device, ' // &
89 ' but ok if used on cpu and for io')
103 else if (dir .eq. 2)
then
105 else if (dir .eq. 3)
then
108 call neko_error(
'Invalid dir for geopmetric comm')
110 allocate(this%dir_el(nelv))
111 allocate(this%el_lvl(nelv))
112 allocate(this%pt_lvl(lx, lx, lx, nelv))
113 allocate(min_vals(lx, lx, lx, nelv))
114 allocate(min_temp(lx, lx, lx, nelv))
127 el_dim(1, :) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
128 this%msh%elements(i)%e%pts(2)%p%x)
129 el_dim(1, :) = el_dim(1, :)/norm2(el_dim(1, :))
130 el_dim(2, :) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
131 this%msh%elements(i)%e%pts(3)%p%x)
132 el_dim(2, :) = el_dim(2, :)/norm2(el_dim(2, :))
133 el_dim(3, :) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
134 this%msh%elements(i)%e%pts(5)%p%x)
135 el_dim(3, :) = el_dim(3, :)/norm2(el_dim(3, :))
138 this%dir_el(i) = maxloc(el_dim(:, this%dir), dim = 1)
140 glb_min =
glmin(line, n)
141 glb_max =
glmax(line, n)
147 el_min = minval(line(:, :, :, e))
148 min_vals(:, :, :, e) = el_min
151 if (
relcmp(el_min, glb_min, this%tol))
then
152 if (this%el_lvl(e) .eq. -1) this%el_lvl(e) = i
159 do while (.not.
relcmp(
glmax(min_vals, n), glb_min, this%tol))
163 if (this%dir_el(e) .eq. 1)
then
164 if (line(1, 1, 1, e) .gt. line(lx, 1, 1, e))
then
165 min_vals(lx, :, :, e) = glb_max
167 min_vals(1, :, :, e) = glb_max
170 if (this%dir_el(e) .eq. 2)
then
171 if (line(1, 1, 1, e) .gt. line(1, lx, 1, e))
then
172 min_vals(:, lx, :, e) = glb_max
174 min_vals(:, 1, :, e) = glb_max
177 if (this%dir_el(e) .eq. 3)
then
178 if (line(1, 1, 1, e) .gt. line(1, 1, lx, e))
then
179 min_vals(:, :, lx, e) = glb_max
181 min_vals(:, :, 1, e) = glb_max
191 call coef%gs_h%op(min_vals, n, gs_op_add)
197 call col2(min_vals, coef%mult, n)
198 call cmult(min_temp, -1.0_rp, n)
199 call add2s1(min_vals, min_temp, 2.0_rp, n)
207 el_min = minval(min_vals(:, :, :, e))
208 min_vals(:, :, :, e) = el_min
209 if (
relcmp(el_min, glb_min, this%tol))
then
210 if (this%el_lvl(e) .eq. -1) this%el_lvl(e) = i
214 this%n_el_lvls =
glimax(this%el_lvl, nelv)
215 this%n_gll_lvls = this%n_el_lvls*lx
220 lvl = lx * (this%el_lvl(e) - 1) + i
221 if (this%dir_el(e) .eq. 1)
then
222 if (line(1, 1, 1, e) .gt. line(lx, 1, 1, e))
then
223 this%pt_lvl(lx-i+1, :, :, e) = lvl
225 this%pt_lvl(i, :, :, e) = lvl
228 if (this%dir_el(e) .eq. 2)
then
229 if (line(1, 1, 1, e) .gt. line(1, lx, 1, e))
then
230 this%pt_lvl(:, lx-i+1, :, e) = lvl
232 this%pt_lvl(:, i, :, e) = lvl
235 if (this%dir_el(e) .eq. 3)
then
236 if (line(1, 1, 1, e) .gt. line(1, 1, lx, e))
then
237 this%pt_lvl(:, :, lx-i+1, e) = lvl
239 this%pt_lvl(:, :, i, e) = lvl
244 if (
allocated(min_vals))
deallocate(min_vals)
245 if (c_associated(min_vals_d))
call device_free(min_vals_d)
246 if (
allocated(min_temp))
deallocate(min_temp)
247 allocate(this%volume_per_gll_lvl(this%n_gll_lvls))
248 this%volume_per_gll_lvl = 0.0_rp
250 this%volume_per_gll_lvl(this%pt_lvl(i, 1, 1, 1)) = &
251 this%volume_per_gll_lvl(this%pt_lvl(i, 1, 1, 1)) + &
254 call mpi_allreduce(mpi_in_place, this%volume_per_gll_lvl, this%n_gll_lvls, &
303 class(
map_1d_t),
intent(inout) :: this
305 type(
matrix_t),
intent(inout) :: avg_planes
306 integer :: n, ierr, j, i
307 real(kind=
rp) :: coord
308 call avg_planes%free()
309 call avg_planes%init(this%n_gll_lvls,
field_list%size() + 1)
314 if (this%dir .eq. 1) coord = this%dof%x(i,1,1,1)
315 if (this%dir .eq. 2) coord = this%dof%y(i,1,1,1)
316 if (this%dir .eq. 3) coord = this%dof%z(i,1,1,1)
317 avg_planes%x(this%pt_lvl(i,1,1,1), 1) = &
318 avg_planes%x(this%pt_lvl(i,1,1,1), 1) + &
319 coord * this%coef%B(i,1,1,1) / &
320 this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
324 avg_planes%x(this%pt_lvl(i,1,1,1), j) = &
325 avg_planes%x(this%pt_lvl(i,1,1,1), j) + &
326 field_list%items(j-1)%ptr%x(i,1,1,1) * this%coef%B(i,1,1,1) &
327 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
331 call mpi_allreduce(mpi_in_place, avg_planes%x, &
345 class(
map_1d_t),
intent(inout) :: this
348 type(
matrix_t),
intent(inout) :: avg_planes
349 integer :: n, ierr, j, i
350 real(kind=
rp) :: coord
352 call avg_planes%free()
353 call avg_planes%init(this%n_gll_lvls,
size(vector_ptr) + 1)
359 if (this%dir .eq. 1) coord = this%dof%x(i,1,1,1)
360 if (this%dir .eq. 2) coord = this%dof%y(i,1,1,1)
361 if (this%dir .eq. 3) coord = this%dof%z(i,1,1,1)
362 avg_planes%x(this%pt_lvl(i,1,1,1), 1) = &
363 avg_planes%x(this%pt_lvl(i,1,1,1), 1) + &
364 coord * this%coef%B(i,1,1,1) / &
365 this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
367 do j = 2,
size(vector_ptr) + 1
369 avg_planes%x(this%pt_lvl(i,1,1,1), j) = &
370 avg_planes%x(this%pt_lvl(i,1,1,1), j) + &
371 vector_ptr(j-1)%ptr%x(i)*this%coef%B(i,1,1,1) &
372 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
375 call mpi_allreduce(mpi_in_place, avg_planes%x, &