70 type(
coef_t),
intent(inout),
target :: coef
71 integer,
intent(in) :: dir
72 real(kind=
rp),
intent(in) :: tol
73 integer :: nelv, lx, n, i, e, lvl, ierr
74 real(kind=
rp),
contiguous,
pointer :: line(:,:,:,:)
75 real(kind=
rp),
allocatable :: min_vals(:,:,:,:)
76 real(kind=
rp),
allocatable :: min_temp(:,:,:,:)
77 type(c_ptr) :: min_vals_d = c_null_ptr
78 real(kind=
rp) :: el_dim(3,3), glb_min, glb_max, el_min
82 if (neko_bcknd_device .eq. 1)
then
84 call neko_warning(
'map_1d does not copy indices to device,'// &
85 ' but ok if used on cpu and for io')
99 else if (dir .eq. 2)
then
101 else if(dir .eq. 3)
then
104 call neko_error(
'Invalid dir for geopmetric comm')
106 allocate(this%dir_el(nelv))
107 allocate(this%el_lvl(nelv))
108 allocate(this%pt_lvl(lx, lx, lx, nelv))
109 allocate(min_vals(lx, lx, lx, nelv))
110 allocate(min_temp(lx, lx, lx, nelv))
112 if (neko_bcknd_device .eq. 1)
then
123 el_dim(1,:) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
124 this%msh%elements(i)%e%pts(2)%p%x)
125 el_dim(1,:) = el_dim(1,:)/norm2(el_dim(1,:))
126 el_dim(2,:) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
127 this%msh%elements(i)%e%pts(3)%p%x)
128 el_dim(2,:) = el_dim(2,:)/norm2(el_dim(2,:))
129 el_dim(3,:) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
130 this%msh%elements(i)%e%pts(5)%p%x)
131 el_dim(3,:) = el_dim(3,:)/norm2(el_dim(3,:))
134 this%dir_el(i) = maxloc(el_dim(:,this%dir),dim=1)
136 glb_min =
glmin(line,n)
137 glb_max =
glmax(line,n)
143 el_min = minval(line(:,:,:,e))
144 min_vals(:,:,:,e) = el_min
146 if (
relcmp(el_min, glb_min, this%tol))
then
147 if(this%el_lvl(e) .eq. -1) this%el_lvl(e) = i
154 do while (.not.
relcmp(
glmax(min_vals,n), glb_min, this%tol))
158 if (this%dir_el(e) .eq. 1)
then
159 if (line(1,1,1,e) .gt. line(lx,1,1,e))
then
160 min_vals(lx,:,:,e) = glb_max
162 min_vals(1,:,:,e) = glb_max
165 if (this%dir_el(e) .eq. 2)
then
166 if (line(1,1,1,e) .gt. line(1,lx,1,e))
then
167 min_vals(:,lx,:,e) = glb_max
169 min_vals(:,1,:,e) = glb_max
172 if (this%dir_el(e) .eq. 3)
then
173 if (line(1,1,1,e) .gt. line(1,1,lx,e))
then
174 min_vals(:,:,lx,e) = glb_max
176 min_vals(:,:,1,e) = glb_max
182 if (neko_bcknd_device .eq. 1) &
186 call coef%gs_h%op(min_vals, n, gs_op_add)
187 if (neko_bcknd_device .eq. 1) &
192 call col2(min_vals, coef%mult, n)
193 call cmult(min_temp, -1.0_rp, n)
194 call add2s1(min_vals, min_temp, 2.0_rp, n)
202 el_min = minval(min_vals(:,:,:,e))
203 min_vals(:,:,:,e) = el_min
204 if (
relcmp(el_min, glb_min, this%tol))
then
205 if (this%el_lvl(e) .eq. -1) this%el_lvl(e) = i
209 this%n_el_lvls =
glimax(this%el_lvl,nelv)
210 this%n_gll_lvls = this%n_el_lvls*lx
215 lvl = lx * (this%el_lvl(e) - 1) + i
216 if (this%dir_el(e) .eq. 1)
then
217 if (line(1,1,1,e) .gt. line(lx,1,1,e))
then
218 this%pt_lvl(lx-i+1,:,:,e) = lvl
220 this%pt_lvl(i,:,:,e) = lvl
223 if (this%dir_el(e) .eq. 2)
then
224 if (line(1,1,1,e) .gt. line(1,lx,1,e))
then
225 this%pt_lvl(:,lx-i+1,:,e) = lvl
227 this%pt_lvl(:,i,:,e) = lvl
230 if (this%dir_el(e) .eq. 3)
then
231 if (line(1,1,1,e) .gt. line(1,1,lx,e))
then
232 this%pt_lvl(:,:,lx-i+1,e) = lvl
234 this%pt_lvl(:,:,i,e) = lvl
239 if(
allocated(min_vals))
deallocate(min_vals)
240 if(c_associated(min_vals_d))
call device_free(min_vals_d)
241 if(
allocated(min_temp))
deallocate(min_temp)
242 allocate(this%volume_per_gll_lvl(this%n_gll_lvls))
243 this%volume_per_gll_lvl =0.0_rp
245 this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1)) = &
246 this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1)) + coef%B(i,1,1,1)
248 call mpi_allreduce(mpi_in_place,this%volume_per_gll_lvl, this%n_gll_lvls, &
297 class(
map_1d_t),
intent(inout) :: this
299 type(
matrix_t),
intent(inout) :: avg_planes
300 integer :: n, ierr, j, i
301 real(kind=
rp) :: coord
302 call avg_planes%free()
303 call avg_planes%init(this%n_gll_lvls,
field_list%size()+1)
308 if (this%dir .eq. 1) coord = this%dof%x(i,1,1,1)
309 if (this%dir .eq. 2) coord = this%dof%y(i,1,1,1)
310 if (this%dir .eq. 3) coord = this%dof%z(i,1,1,1)
311 avg_planes%x(this%pt_lvl(i,1,1,1),1) = &
312 avg_planes%x(this%pt_lvl(i,1,1,1),1) + coord*this%coef%B(i,1,1,1) &
313 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
317 avg_planes%x(this%pt_lvl(i,1,1,1),j) = &
318 avg_planes%x(this%pt_lvl(i,1,1,1),j) + &
319 field_list%items(j-1)%ptr%x(i,1,1,1)*this%coef%B(i,1,1,1) &
320 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
324 call mpi_allreduce(mpi_in_place, avg_planes%x, (
field_list%size()+1)*this%n_gll_lvls, &
337 class(
map_1d_t),
intent(inout) :: this
340 type(
matrix_t),
intent(inout) :: avg_planes
341 integer :: n, ierr, j, i
342 real(kind=
rp) :: coord
344 call avg_planes%free()
345 call avg_planes%init(this%n_gll_lvls,
size(vector_ptr)+1)
351 if (this%dir .eq. 1) coord = this%dof%x(i,1,1,1)
352 if (this%dir .eq. 2) coord = this%dof%y(i,1,1,1)
353 if (this%dir .eq. 3) coord = this%dof%z(i,1,1,1)
354 avg_planes%x(this%pt_lvl(i,1,1,1),1) = &
355 avg_planes%x(this%pt_lvl(i,1,1,1),1) + coord*this%coef%B(i,1,1,1) &
356 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
358 do j = 2,
size(vector_ptr)+1
360 avg_planes%x(this%pt_lvl(i,1,1,1),j) = &
361 avg_planes%x(this%pt_lvl(i,1,1,1),j) + &
362 vector_ptr(j-1)%ptr%x(i)*this%coef%B(i,1,1,1) &
363 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
366 call mpi_allreduce(mpi_in_place,avg_planes%x, (
size(vector_ptr)+1)*this%n_gll_lvls, &