Neko 1.99.6
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
elementwise_filter.f90
Go to the documentation of this file.
1! Copyright (c) 2024, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
33!
36 use num_types, only : rp
37 use filter, only : filter_t
38 use math, only : rzero, rone, copy
39 use field, only : field_t
40 use coefs, only : coef_t
41 use utils, only : neko_error
43 use json_module, only : json_file
45 use speclib, only : zwgll, legendre_poly
46 use matrix, only : matrix_t
47 use mxm_wrapper, only : mxm
48 use tensor, only : tnsr3d, trsp
51 use device_math, only : device_cfill
52 use, intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr
53 implicit none
54 private
55
57 type, public, extends(filter_t) :: elementwise_filter_t
60 character(len=:), allocatable :: filter_type
62 integer :: nx
64 integer :: nt
66 real(kind=rp), allocatable :: fh(:,:), fht(:,:)
67 type(c_ptr) :: fh_d = c_null_ptr
68 type(c_ptr) :: fht_d = c_null_ptr
70 real(kind=rp), allocatable :: transfer(:)
71 contains
73 procedure, pass(this) :: init => elementwise_filter_init_from_json
75 procedure, pass(this) :: init_from_components => &
78 procedure, pass(this) :: free => elementwise_filter_free
80 procedure, pass(this) :: build_1d
82 procedure, pass(this) :: apply => elementwise_field_filter_3d
84
85contains
87 subroutine elementwise_filter_init_from_json(this, json, coef)
88 class(elementwise_filter_t), intent(inout) :: this
89 type(json_file), intent(inout) :: json
90 type(coef_t), intent(in), target :: coef
91 real(kind=rp), allocatable :: transfer(:)
92 character(len=:), allocatable :: filter_type
93
94 call json_get_or_default(json, "elementwise_filter_type", &
95 filter_type, "nonBoyd")
96
97 if (json%valid_path('transfer_function')) then
98 call json_get(json, 'transfer_function', transfer)
99 end if
100
101 if (allocated(transfer)) then
102 call this%init_from_components(coef, filter_type, transfer)
103 else
104 call this%init_from_components(coef, filter_type)
105 end if
106
107
108 if (allocated(transfer)) then
109 deallocate(transfer)
110 end if
111
112 if (allocated(filter_type)) then
113 deallocate(filter_type)
114 end if
115
117
122 subroutine elementwise_filter_init_from_components(this, coef, filter_type, &
123 transfer)
124 class(elementwise_filter_t), intent(inout) :: this
125 type(coef_t), intent(in), target :: coef
126 character(len=*), intent(in) :: filter_type
127 real(kind=rp), intent(in), optional :: transfer(:)
128 integer :: nx
129
130 call this%free()
131
132 ! Filter assumes lx = ly = lz
133 call this%init_base(coef)
134 nx = coef%dof%xh%lx
135 this%nx = nx
136 this%nt = nx ! initialize as if nothing is filtered yet
137 this%filter_type = filter_type
138
139 allocate(this%fh(nx, nx))
140 allocate(this%fht(nx, nx))
141 allocate(this%transfer(nx))
142
143 call rzero(this%fh, nx*nx)
144 call rzero(this%fht, nx*nx)
145 call rone(this%transfer, nx) ! initialize as if nothing is filtered yet
146
147 if (present(transfer)) then
148 if (size(transfer) .eq. nx) then
149 this%transfer = transfer
150 else
151 call neko_error("The transfer function of the elementwise " // &
152 "filter must correspond the order of the polynomial")
153 end if
154 end if
155
156 if (neko_bcknd_device .eq. 1) then
157 call device_map(this%fh, this%fh_d, this%nx * this%nx)
158 call device_map(this%fht, this%fht_d, this%nx * this%nx)
159 call device_cfill(this%fh_d, 0.0_rp, this%nx * this%nx)
160 call device_cfill(this%fht_d, 0.0_rp, this%nx * this%nx)
161 ! Order the async fills against the host-side build_1d; on
162 ! unified memory the device pointers may alias fh/fht
163 call device_sync()
164 end if
165
166 call this%build_1d()
167
169
171 subroutine elementwise_filter_free(this)
172 class(elementwise_filter_t), intent(inout) :: this
173
174 if (allocated(this%filter_type)) then
175 deallocate(this%filter_type)
176 end if
177
178 if (allocated(this%fh)) then
179 if (neko_bcknd_device .eq. 1) then
180 call device_unmap(this%fh, this%fh_d)
181 end if
182 deallocate(this%fh)
183 end if
184
185 if (allocated(this%fht)) then
186 if (neko_bcknd_device .eq. 1) then
187 call device_unmap(this%fht, this%fht_d)
188 end if
189 deallocate(this%fht)
190 end if
191
192 if (allocated(this%transfer)) then
193 deallocate(this%transfer)
194 end if
195
196 this%filter_type = ""
197 this%nx = 0
198 this%nt = 0
199
200 call this%free_base()
201
202 end subroutine elementwise_filter_free
203
205 subroutine build_1d(this)
206 class(elementwise_filter_t), intent(inout) :: this
207
208 call build_1d_cpu(this%fh, this%fht, this%transfer, &
209 this%nx, this%filter_type)
210 if (neko_bcknd_device .eq. 1) then
211 call device_memcpy(this%fh, this%fh_d, &
212 this%nx * this%nx, host_to_device, sync = .false.)
213 call device_memcpy(this%fht, this%fht_d, &
214 this%nx * this%nx, host_to_device, sync = .false.)
215 end if
216
217 end subroutine build_1d
218
220 subroutine elementwise_field_filter_3d(this, F_out, F_in)
221 class(elementwise_filter_t), intent(inout) :: this
222 type(field_t), intent(inout) :: F_out
223 type(field_t), intent(in) :: F_in
224
225 ! F_out = fh x fh x fh x F_in
226 call tnsr3d(f_out%x, this%nx, f_in%x, this%nx, this%fh, this%fht, &
227 this%fht, this%coef%msh%nelv)
228
229 end subroutine elementwise_field_filter_3d
230
238 subroutine build_1d_cpu(fh, fht, transfer, nx, filter_type)
239 integer, intent(in) :: nx
240 real(kind=rp), intent(inout) :: fh(nx, nx), fht(nx, nx)
241 real(kind=rp), intent(in) :: transfer(nx)
242 real(kind=rp) :: diag(nx, nx), rmult(nx), lj(nx), zpts(nx)
243 type(matrix_t) :: phi, pht
244 integer :: n, i, j, k
245 real(kind=rp) :: z
246 character(len=*), intent(in) :: filter_type
247
248 call phi%init(nx, nx)
249 call pht%init(nx, nx)
250
251 call zwgll(zpts, rmult, nx)
252
253 n = nx-1
254 do j = 1, nx
255 z = zpts(j)
256 call legendre_poly(lj, z, n)
257 select case (filter_type)
258 case ("Boyd")
259 pht%x(1,j) = lj(1)
260 pht%x(2,j) = lj(2)
261 do k = 3, nx
262 pht%x(k, j) = lj(k) - lj(k - 2)
263 end do
264 case ("nonBoyd")
265 pht%x(:,j) = lj
266 end select
267 end do
268
269 call trsp(phi%x, nx, pht%x, nx)
270 pht%x = phi%x
271
272 call pht%inverse(0) ! "0" for cpu implementation
273
274 diag = 0.0_rp
275
276 do i = 1, nx
277 diag(i, i) = transfer(i)
278 end do
279
280 call mxm (diag, nx, pht%x, nx, fh, nx) ! -1
281 call mxm (phi%x, nx, fh, nx, pht%x, nx) ! V D V
282
283 call copy (fh, pht%x, nx*nx)
284 call trsp (fht, nx, fh, nx)
285
286 end subroutine build_1d_cpu
287
288end module elementwise_filter
Map a Fortran array to a device (allocate and associate)
Definition device.F90:83
Copy data between host and device (or device and device)
Definition device.F90:72
Synchronize a device or stream.
Definition device.F90:119
Unmap a Fortran array from a device (deassociate and free)
Definition device.F90:89
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Coefficients.
Definition coef.f90:34
subroutine, public device_cfill(a_d, c, n, strm)
Set all elements to a constant c .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:48
Implements elementwise_filter_t.
subroutine build_1d_cpu(fh, fht, transfer, nx, filter_type)
Build the 1d filter for an element on the CPU. Suppose field x is filtered into x_hat by x_hat = fh*x...
subroutine elementwise_filter_init_from_components(this, coef, filter_type, transfer)
Actual Constructor.
subroutine elementwise_filter_init_from_json(this, json, coef)
Constructor.
subroutine elementwise_filter_free(this)
Destructor.
subroutine build_1d(this)
Build the 1d filter for an element.
subroutine elementwise_field_filter_3d(this, f_out, f_in)
Filter a 3D field.
Defines a field.
Definition field.f90:34
Filter to be applied to a scalar field.
Definition filter.f90:38
Utilities for retrieving parameters from the case files.
Definition math.f90:60
subroutine, public rone(a, n)
Set all elements to one.
Definition math.f90:277
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:291
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:235
Defines a matrix.
Definition matrix.f90:34
Wrapper for all matrix-matrix product implementations.
subroutine, public mxm(a, n1, b, n2, c, n3)
Compute matrix-matrix product for contiguously packed matrices A,B, and C.
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
LIBRARY ROUTINES FOR SPECTRAL METHODS.
Definition speclib.f90:149
subroutine zwgll(z, w, np)
Generate NP Gauss-Lobatto Legendre points (Z) and weights (W) associated with Jacobi polynomial P(N)(...
Definition speclib.f90:180
subroutine legendre_poly(l, x, n)
Evaluate Legendre polynomials of degrees 0-N at point x and store in array L.
Definition speclib.f90:1004
Tensor operations.
Definition tensor.f90:61
subroutine, public trsp(a, lda, b, ldb)
Transpose of a rectangular tensor .
Definition tensor.f90:124
subroutine, public tnsr3d(v, nv, u, nu, a, bt, ct, nelv)
Tensor product performed on nelv elements.
Definition tensor.f90:234
Utilities.
Definition utils.f90:35
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:63
Implements the elementwise filter for SEM.
Base abstract class for filter.
Definition filter.f90:47