71 type(
coef_t),
intent(inout),
target :: coef
72 integer,
intent(in) :: dir
73 real(kind=
rp),
intent(in) :: tol
74 integer :: nelv, lx, n, i, e, lvl, ierr
75 real(kind=
rp),
contiguous,
pointer :: line(:,:,:,:)
76 real(kind=
rp),
allocatable :: min_vals(:,:,:,:)
77 real(kind=
rp),
allocatable :: min_temp(:,:,:,:)
78 type(c_ptr) :: min_vals_d = c_null_ptr
79 real(kind=
rp) :: el_dim(3,3), glb_min, glb_max, el_min
83 if (neko_bcknd_device .eq. 1)
then
85 call neko_warning(
'map_1d does not copy indices to device,'// &
86 ' but ok if used on cpu and for io')
100 else if (dir .eq. 2)
then
102 else if(dir .eq. 3)
then
105 call neko_error(
'Invalid dir for geopmetric comm')
107 allocate(this%dir_el(nelv))
108 allocate(this%el_lvl(nelv))
109 allocate(this%pt_lvl(lx, lx, lx, nelv))
110 allocate(min_vals(lx, lx, lx, nelv))
111 allocate(min_temp(lx, lx, lx, nelv))
113 if (neko_bcknd_device .eq. 1)
then
124 el_dim(1,:) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
125 this%msh%elements(i)%e%pts(2)%p%x)
126 el_dim(1,:) = el_dim(1,:)/norm2(el_dim(1,:))
127 el_dim(2,:) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
128 this%msh%elements(i)%e%pts(3)%p%x)
129 el_dim(2,:) = el_dim(2,:)/norm2(el_dim(2,:))
130 el_dim(3,:) = abs(this%msh%elements(i)%e%pts(1)%p%x - &
131 this%msh%elements(i)%e%pts(5)%p%x)
132 el_dim(3,:) = el_dim(3,:)/norm2(el_dim(3,:))
135 this%dir_el(i) = maxloc(el_dim(:,this%dir),dim=1)
137 glb_min =
glmin(line,n)
138 glb_max =
glmax(line,n)
144 el_min = minval(line(:,:,:,e))
145 min_vals(:,:,:,e) = el_min
147 if (
relcmp(el_min, glb_min, this%tol))
then
148 if(this%el_lvl(e) .eq. -1) this%el_lvl(e) = i
155 do while (.not.
relcmp(
glmax(min_vals,n), glb_min, this%tol))
159 if (this%dir_el(e) .eq. 1)
then
160 if (line(1,1,1,e) .gt. line(lx,1,1,e))
then
161 min_vals(lx,:,:,e) = glb_max
163 min_vals(1,:,:,e) = glb_max
166 if (this%dir_el(e) .eq. 2)
then
167 if (line(1,1,1,e) .gt. line(1,lx,1,e))
then
168 min_vals(:,lx,:,e) = glb_max
170 min_vals(:,1,:,e) = glb_max
173 if (this%dir_el(e) .eq. 3)
then
174 if (line(1,1,1,e) .gt. line(1,1,lx,e))
then
175 min_vals(:,:,lx,e) = glb_max
177 min_vals(:,:,1,e) = glb_max
183 if (neko_bcknd_device .eq. 1) &
187 call coef%gs_h%op(min_vals, n, gs_op_add)
188 if (neko_bcknd_device .eq. 1) &
193 call col2(min_vals, coef%mult, n)
194 call cmult(min_temp, -1.0_rp, n)
195 call add2s1(min_vals, min_temp, 2.0_rp, n)
203 el_min = minval(min_vals(:,:,:,e))
204 min_vals(:,:,:,e) = el_min
205 if (
relcmp(el_min, glb_min, this%tol))
then
206 if (this%el_lvl(e) .eq. -1) this%el_lvl(e) = i
210 this%n_el_lvls =
glimax(this%el_lvl,nelv)
211 this%n_gll_lvls = this%n_el_lvls*lx
216 lvl = lx * (this%el_lvl(e) - 1) + i
217 if (this%dir_el(e) .eq. 1)
then
218 if (line(1,1,1,e) .gt. line(lx,1,1,e))
then
219 this%pt_lvl(lx-i+1,:,:,e) = lvl
221 this%pt_lvl(i,:,:,e) = lvl
224 if (this%dir_el(e) .eq. 2)
then
225 if (line(1,1,1,e) .gt. line(1,lx,1,e))
then
226 this%pt_lvl(:,lx-i+1,:,e) = lvl
228 this%pt_lvl(:,i,:,e) = lvl
231 if (this%dir_el(e) .eq. 3)
then
232 if (line(1,1,1,e) .gt. line(1,1,lx,e))
then
233 this%pt_lvl(:,:,lx-i+1,e) = lvl
235 this%pt_lvl(:,:,i,e) = lvl
240 if(
allocated(min_vals))
deallocate(min_vals)
241 if(c_associated(min_vals_d))
call device_free(min_vals_d)
242 if(
allocated(min_temp))
deallocate(min_temp)
243 allocate(this%volume_per_gll_lvl(this%n_gll_lvls))
244 this%volume_per_gll_lvl =0.0_rp
246 this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1)) = &
247 this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1)) + coef%B(i,1,1,1)
249 call mpi_allreduce(mpi_in_place,this%volume_per_gll_lvl, this%n_gll_lvls, &
298 class(
map_1d_t),
intent(inout) :: this
300 type(
matrix_t),
intent(inout) :: avg_planes
301 integer :: n, ierr, j, i
302 real(kind=
rp) :: coord
303 call avg_planes%free()
304 call avg_planes%init(this%n_gll_lvls,
field_list%size()+1)
309 if (this%dir .eq. 1) coord = this%dof%x(i,1,1,1)
310 if (this%dir .eq. 2) coord = this%dof%y(i,1,1,1)
311 if (this%dir .eq. 3) coord = this%dof%z(i,1,1,1)
312 avg_planes%x(this%pt_lvl(i,1,1,1),1) = &
313 avg_planes%x(this%pt_lvl(i,1,1,1),1) + coord*this%coef%B(i,1,1,1) &
314 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
318 avg_planes%x(this%pt_lvl(i,1,1,1),j) = &
319 avg_planes%x(this%pt_lvl(i,1,1,1),j) + &
320 field_list%items(j-1)%ptr%x(i,1,1,1)*this%coef%B(i,1,1,1) &
321 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
325 call mpi_allreduce(mpi_in_place, avg_planes%x, (
field_list%size()+1)*this%n_gll_lvls, &
338 class(
map_1d_t),
intent(inout) :: this
341 type(
matrix_t),
intent(inout) :: avg_planes
342 integer :: n, ierr, j, i
343 real(kind=
rp) :: coord
345 call avg_planes%free()
346 call avg_planes%init(this%n_gll_lvls,
size(vector_ptr)+1)
352 if (this%dir .eq. 1) coord = this%dof%x(i,1,1,1)
353 if (this%dir .eq. 2) coord = this%dof%y(i,1,1,1)
354 if (this%dir .eq. 3) coord = this%dof%z(i,1,1,1)
355 avg_planes%x(this%pt_lvl(i,1,1,1),1) = &
356 avg_planes%x(this%pt_lvl(i,1,1,1),1) + coord*this%coef%B(i,1,1,1) &
357 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
359 do j = 2,
size(vector_ptr)+1
361 avg_planes%x(this%pt_lvl(i,1,1,1),j) = &
362 avg_planes%x(this%pt_lvl(i,1,1,1),j) + &
363 vector_ptr(j-1)%ptr%x(i)*this%coef%B(i,1,1,1) &
364 /this%volume_per_gll_lvl(this%pt_lvl(i,1,1,1))
367 call mpi_allreduce(mpi_in_place,avg_planes%x, (
size(vector_ptr)+1)*this%n_gll_lvls, &