19 use,
intrinsic :: iso_c_binding
29 integer,
allocatable :: dir_el(:)
31 integer,
allocatable :: el_lvl(:)
33 integer,
allocatable :: pt_lvl(:,:,:,:)
42 type(
coef_t),
pointer :: coef => null()
44 type(
mesh_t),
pointer :: msh => null()
48 real(kind=
rp) :: tol = 1e-7
50 real(kind=
rp),
allocatable :: volume_per_gll_lvl(:)
56 generic :: init => init_int, init_char
63 generic :: average_planes => average_planes_fld_lst, average_planes_vec_ptr
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, &
256 type(
coef_t),
intent(inout),
target :: coef
257 character(len=*),
intent(in) :: dir
258 real(kind=
rp),
intent(in) :: tol
261 if (trim(dir) .eq.
'yz' .or. trim(dir) .eq.
'zy')
then
263 else if (trim(dir) .eq.
'xz' .or. trim(dir) .eq.
'zx')
then
265 else if (trim(dir) .eq.
'xy' .or. trim(dir) .eq.
'yx')
then
268 call neko_error(
'homogenous direction not supported')
271 call this%init(coef,idir,tol)
278 if(
allocated(this%dir_el))
deallocate(this%dir_el)
279 if(
allocated(this%el_lvl))
deallocate(this%el_lvl)
280 if(
allocated(this%pt_lvl))
deallocate(this%pt_lvl)
281 if(
associated(this%dof))
nullify(this%dof)
282 if(
associated(this%msh))
nullify(this%msh)
283 if(
associated(this%coef))
nullify(this%coef)
284 if(
allocated(this%volume_per_gll_lvl))
deallocate(this%volume_per_gll_lvl)
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, &
Map a Fortran array to a device (allocate and associate)
Copy data between host and device (or device and device)
type(mpi_comm) neko_comm
MPI communicator.
type(mpi_datatype) mpi_real_precision
MPI type for working precision of REAL types.
integer pe_size
MPI size of communicator.
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
subroutine, public device_free(x_d)
Deallocate memory on the device.
integer, parameter, public device_to_host
Defines a mapping of the degrees of freedom.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
Creates a 1d GLL point map along a specified direction based on the connectivity in the mesh.
subroutine map_1d_init(this, coef, dir, tol)
subroutine map_1d_free(this)
subroutine map_1d_average_field_list(this, avg_planes, field_list)
Computes average if field list in two directions and outputs matrix with averaged values avg_planes c...
subroutine map_1d_init_char(this, coef, dir, tol)
subroutine map_1d_average_vector_ptr(this, avg_planes, vector_ptr)
Computes average if vector_pt in two directions and outputs matrix with averaged values avg_planes co...
subroutine, public cmult(a, c, n)
Multiplication by constant c .
subroutine, public add2s1(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on first argument)
integer function, public glimin(a, n)
Min of an integer vector of length n.
subroutine, public col2(a, b, n)
Vector multiplication .
real(kind=rp) function, public glmax(a, n)
Max of a vector of length n.
integer function, public glimax(a, n)
Max of an integer vector of length n.
real(kind=rp) function, public glmin(a, n)
Min of a vector of length n.
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
field_list_t, To be able to group fields together
Type that encapsulates a mapping from each gll point in the mesh to its corresponding (global) GLL po...
The function space for the SEM solution fields.