Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
adv_dealias.f90
Go to the documentation of this file.
1! Copyright (c) 2021-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!
35 use advection, only : advection_t
36 use num_types, only : rp
37 use math, only : vdot3, sub2
38 use space, only : space_t, gl
39 use field, only : field_t
40 use coefs, only : coef_t
44 use utils, only : neko_error
45 use operators, only : opgrad
48 use, intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr, c_associated
49 implicit none
50 private
51
53 type, public, extends(advection_t) :: adv_dealias_t
55 type(coef_t) :: coef_gl
57 type(coef_t), pointer :: coef_gll
59 type(interpolator_t) :: gll_to_gl
61 type(space_t) :: xh_gl
63 type(space_t), pointer :: xh_gll
64 real(kind=rp), allocatable :: temp(:), tbf(:)
66 real(kind=rp), allocatable :: tx(:), ty(:), tz(:)
67 real(kind=rp), allocatable :: vr(:), vs(:), vt(:)
69 type(c_ptr) :: temp_d = c_null_ptr
71 type(c_ptr) :: tbf_d = c_null_ptr
73 type(c_ptr) :: tx_d = c_null_ptr
75 type(c_ptr) :: ty_d = c_null_ptr
77 type(c_ptr) :: tz_d = c_null_ptr
79 type(c_ptr) :: vr_d = c_null_ptr
81 type(c_ptr) :: vs_d = c_null_ptr
83 type(c_ptr) :: vt_d = c_null_ptr
84
85 contains
88 procedure, pass(this) :: compute => compute_advection_dealias
91 procedure, pass(this) :: compute_scalar => compute_scalar_advection_dealias
93 procedure, pass(this) :: compute_ale => compute_ale_advection_dealias
95 procedure, pass(this) :: recompute_metrics => recompute_metrics_dealias
97 procedure, pass(this) :: init => init_dealias
99 procedure, pass(this) :: free => free_dealias
100 end type adv_dealias_t
101
102contains
103
107 subroutine init_dealias(this, lxd, coef)
108 class(adv_dealias_t), target, intent(inout) :: this
109 integer, intent(in) :: lxd
110 type(coef_t), intent(inout), target :: coef
111 integer :: nel, n_GL, n
112
113 call this%Xh_GL%init(gl, lxd, lxd, lxd)
114 this%Xh_GLL => coef%Xh
115 this%coef_GLL => coef
116 call this%GLL_to_GL%init(this%Xh_GL, this%Xh_GLL)
117
118 call this%coef_GL%init(this%Xh_GL, coef%msh)
119
120 nel = coef%msh%nelv
121 n_gl = nel*this%Xh_GL%lxyz
122 n = nel*coef%Xh%lxyz
123 call this%GLL_to_GL%map(this%coef_GL%drdx, coef%drdx, nel, this%Xh_GL)
124 call this%GLL_to_GL%map(this%coef_GL%dsdx, coef%dsdx, nel, this%Xh_GL)
125 call this%GLL_to_GL%map(this%coef_GL%dtdx, coef%dtdx, nel, this%Xh_GL)
126 call this%GLL_to_GL%map(this%coef_GL%drdy, coef%drdy, nel, this%Xh_GL)
127 call this%GLL_to_GL%map(this%coef_GL%dsdy, coef%dsdy, nel, this%Xh_GL)
128 call this%GLL_to_GL%map(this%coef_GL%dtdy, coef%dtdy, nel, this%Xh_GL)
129 call this%GLL_to_GL%map(this%coef_GL%drdz, coef%drdz, nel, this%Xh_GL)
130 call this%GLL_to_GL%map(this%coef_GL%dsdz, coef%dsdz, nel, this%Xh_GL)
131 call this%GLL_to_GL%map(this%coef_GL%dtdz, coef%dtdz, nel, this%Xh_GL)
132 if ((neko_bcknd_hip .eq. 1) .or. (neko_bcknd_cuda .eq. 1) .or. &
133 (neko_bcknd_opencl .eq. 1) .or. (neko_bcknd_sx .eq. 1) .or. &
134 (neko_bcknd_xsmm .eq. 1)) then
135 allocate(this%temp(n_gl))
136 allocate(this%tbf(n_gl))
137 allocate(this%tx(n_gl))
138 allocate(this%ty(n_gl))
139 allocate(this%tz(n_gl))
140 allocate(this%vr(n_gl))
141 allocate(this%vs(n_gl))
142 allocate(this%vt(n_gl))
143 end if
144
145 if (neko_bcknd_device .eq. 1) then
146 call device_map(this%temp, this%temp_d, n_gl)
147 call device_map(this%tbf, this%tbf_d, n_gl)
148 call device_map(this%tx, this%tx_d, n_gl)
149 call device_map(this%ty, this%ty_d, n_gl)
150 call device_map(this%tz, this%tz_d, n_gl)
151 call device_map(this%vr, this%vr_d, n_gl)
152 call device_map(this%vs, this%vs_d, n_gl)
153 call device_map(this%vt, this%vt_d, n_gl)
154 end if
155
156 end subroutine init_dealias
157
159 subroutine free_dealias(this)
160 class(adv_dealias_t), intent(inout) :: this
161
162 if (allocated(this%temp)) then
163 deallocate(this%temp)
164 end if
165
166 if (allocated(this%tbf)) then
167 deallocate(this%tbf)
168 end if
169 if (allocated(this%tx)) then
170 deallocate(this%tx)
171 end if
172 if (allocated(this%ty)) then
173 deallocate(this%ty)
174 end if
175 if (allocated(this%tz)) then
176 deallocate(this%tz)
177 end if
178 if (allocated(this%vr)) then
179 deallocate(this%vr)
180 end if
181 if (allocated(this%vs)) then
182 deallocate(this%vs)
183 end if
184 if (allocated(this%vt)) then
185 deallocate(this%vt)
186 end if
187
188 if (c_associated(this%temp_d)) then
189 call device_free(this%temp_d)
190 end if
191
192 if (c_associated(this%tbf_d)) then
193 call device_free(this%tbf_d)
194 end if
195
196 if (c_associated(this%tx_d)) then
197 call device_free(this%tx_d)
198 end if
199
200 if (c_associated(this%ty_d)) then
201 call device_free(this%ty_d)
202 end if
203
204 if (c_associated(this%tz_d)) then
205 call device_free(this%tz_d)
206 end if
207
208 if (c_associated(this%vr_d)) then
209 call device_free(this%vr_d)
210 end if
211
212 if (c_associated(this%vs_d)) then
213 call device_free(this%vs_d)
214 end if
215
216 if (c_associated(this%vt_d)) then
217 call device_free(this%vt_d)
218 end if
219
220 call this%coef_GL%free()
221 call this%GLL_to_GL%free()
222 call this%Xh_GL%free()
223
224 nullify(this%Xh_GLL)
225 nullify(this%coef_GLL)
226
227 end subroutine free_dealias
228
229
242 subroutine compute_advection_dealias(this, vx, vy, vz, fx, fy, fz, Xh, &
243 coef, n, dt)
244 class(adv_dealias_t), intent(inout) :: this
245 type(space_t), intent(in) :: Xh
246 type(coef_t), intent(in) :: coef
247 type(field_t), intent(inout) :: vx, vy, vz
248 type(field_t), intent(inout) :: fx, fy, fz
249 integer, intent(in) :: n
250 real(kind=rp), intent(in), optional :: dt
251
252 real(kind=rp), dimension(this%Xh_GL%lxyz) :: tx, ty, tz
253 real(kind=rp), dimension(this%Xh_GL%lxyz) :: tfx, tfy, tfz
254 real(kind=rp), dimension(this%Xh_GL%lxyz) :: vr, vs, vt
255 real(kind=rp), dimension(this%Xh_GLL%lxyz) :: tempx, tempy, tempz
256 integer :: e, i, idx, nel, n_GL
257
258 nel = coef%msh%nelv
259 n_gl = nel * this%Xh_GL%lxyz
260
261 !This is extremely primitive and unoptimized on the device //Karp
262 associate(c_gl => this%coef_GL)
263 if (neko_bcknd_device .eq. 1) then
264 call this%GLL_to_GL%map(this%tx, vx%x, nel, this%Xh_GL)
265 call this%GLL_to_GL%map(this%ty, vy%x, nel, this%Xh_GL)
266 call this%GLL_to_GL%map(this%tz, vz%x, nel, this%Xh_GL)
267
268 call opgrad(this%vr, this%vs, this%vt, this%tx, c_gl)
269 call device_vdot3(this%tbf_d, this%vr_d, this%vs_d, this%vt_d, &
270 this%tx_d, this%ty_d, this%tz_d, n_gl)
271 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
272 call device_sub2(fx%x_d, this%temp_d, n)
273
274
275 call opgrad(this%vr, this%vs, this%vt, this%ty, c_gl)
276 call device_vdot3(this%tbf_d, this%vr_d, this%vs_d, this%vt_d, &
277 this%tx_d, this%ty_d, this%tz_d, n_gl)
278 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
279 call device_sub2(fy%x_d, this%temp_d, n)
280
281 call opgrad(this%vr, this%vs, this%vt, this%tz, c_gl)
282 call device_vdot3(this%tbf_d, this%vr_d, this%vs_d, this%vt_d, &
283 this%tx_d, this%ty_d, this%tz_d, n_gl)
284 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
285 call device_sub2(fz%x_d, this%temp_d, n)
286
287 else if ((neko_bcknd_sx .eq. 1) .or. (neko_bcknd_xsmm .eq. 1)) then
288
289 call this%GLL_to_GL%map(this%tx, vx%x, nel, this%Xh_GL)
290 call this%GLL_to_GL%map(this%ty, vy%x, nel, this%Xh_GL)
291 call this%GLL_to_GL%map(this%tz, vz%x, nel, this%Xh_GL)
292
293 call opgrad(this%vr, this%vs, this%vt, this%tx, c_gl)
294 call vdot3(this%tbf, this%vr, this%vs, this%vt, &
295 this%tx, this%ty, this%tz, n_gl)
296 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
297 call sub2(fx%x, this%temp, n)
298
299
300 call opgrad(this%vr, this%vs, this%vt, this%ty, c_gl)
301 call vdot3(this%tbf, this%vr, this%vs, this%vt, &
302 this%tx, this%ty, this%tz, n_gl)
303 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
304 call sub2(fy%x, this%temp, n)
305
306 call opgrad(this%vr, this%vs, this%vt, this%tz, c_gl)
307 call vdot3(this%tbf, this%vr, this%vs, this%vt, &
308 this%tx, this%ty, this%tz, n_gl)
309 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
310 call sub2(fz%x, this%temp, n)
311
312 else
313 !$omp parallel do private(e, i, idx)
314 do e = 1, coef%msh%nelv
315 call this%GLL_to_GL%map(tx, vx%x(1,1,1,e), 1, this%Xh_GL)
316 call this%GLL_to_GL%map(ty, vy%x(1,1,1,e), 1, this%Xh_GL)
317 call this%GLL_to_GL%map(tz, vz%x(1,1,1,e), 1, this%Xh_GL)
318
319 call opgrad(vr, vs, vt, tx, c_gl, e, e)
320 do i = 1, this%Xh_GL%lxyz
321 tfx(i) = tx(i)*vr(i) + ty(i)*vs(i) + tz(i)*vt(i)
322 end do
323
324 call opgrad(vr, vs, vt, ty, c_gl, e, e)
325 do i = 1, this%Xh_GL%lxyz
326 tfy(i) = tx(i)*vr(i) + ty(i)*vs(i) + tz(i)*vt(i)
327 end do
328
329 call opgrad(vr, vs, vt, tz, c_gl, e, e)
330 do i = 1, this%Xh_GL%lxyz
331 tfz(i) = tx(i)*vr(i) + ty(i)*vs(i) + tz(i)*vt(i)
332 end do
333
334 call this%GLL_to_GL%map(tempx, tfx, 1, this%Xh_GLL)
335 call this%GLL_to_GL%map(tempy, tfy, 1, this%Xh_GLL)
336 call this%GLL_to_GL%map(tempz, tfz, 1, this%Xh_GLL)
337
338 idx = (e-1)*this%Xh_GLL%lxyz+1
339 do concurrent(i = 0:this%Xh_GLL%lxyz-1)
340 fx%x(i+idx,1,1,1) = fx%x(i+idx,1,1,1) - tempx(i+1)
341 fy%x(i+idx,1,1,1) = fy%x(i+idx,1,1,1) - tempy(i+1)
342 fz%x(i+idx,1,1,1) = fz%x(i+idx,1,1,1) - tempz(i+1)
343 end do
344 end do
345 !$omp end parallel do
346 end if
347 end associate
348
349 end subroutine compute_advection_dealias
350
363 subroutine compute_scalar_advection_dealias(this, vx, vy, vz, s, fs, Xh, &
364 coef, n, dt)
365 class(adv_dealias_t), intent(inout) :: this
366 type(field_t), intent(inout) :: vx, vy, vz
367 type(field_t), intent(inout) :: s
368 type(field_t), intent(inout) :: fs
369 type(space_t), intent(in) :: Xh
370 type(coef_t), intent(in) :: coef
371 integer, intent(in) :: n
372 real(kind=rp), intent(in), optional :: dt
373
374 real(kind=rp), dimension(this%Xh_GL%lxyz) :: vx_gl, vy_gl, vz_gl, s_gl
375 real(kind=rp), dimension(this%Xh_GL%lxyz) :: dsdx, dsdy, dsdz
376 real(kind=rp), dimension(this%Xh_GL%lxyz) :: f_gl
377 integer :: e, i, idx, nel, n_GL
378 real(kind=rp), dimension(this%Xh_GLL%lxyz) :: temp
379
380 nel = coef%msh%nelv
381 n_gl = nel * this%Xh_GL%lxyz
382
383 associate(c_gl => this%coef_GL)
384 if (neko_bcknd_device .eq. 1) then
385
386 ! Map advecting velocity onto the higher-order space
387 call this%GLL_to_GL%map(this%tx, vx%x, nel, this%Xh_GL)
388 call this%GLL_to_GL%map(this%ty, vy%x, nel, this%Xh_GL)
389 call this%GLL_to_GL%map(this%tz, vz%x, nel, this%Xh_GL)
390
391 ! Map the scalar onto the high-order space
392 call this%GLL_to_GL%map(this%temp, s%x, nel, this%Xh_GL)
393
394 ! Compute the scalar gradient in the high-order space
395 call opgrad(this%vr, this%vs, this%vt, this%temp, c_gl)
396
397 ! Compute the convective term, i.e dot the velocity with the scalar grad
398 call device_vdot3(this%tbf_d, this%vr_d, this%vs_d, this%vt_d, &
399 this%tx_d, this%ty_d, this%tz_d, n_gl)
400
401 ! Map back to the original space (we reuse this%temp)
402 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
403
404 ! Update the source term
405 call device_sub2(fs%x_d, this%temp_d, n)
406
407 else if ((neko_bcknd_sx .eq. 1) .or. (neko_bcknd_xsmm .eq. 1)) then
408
409 ! Map advecting velocity onto the higher-order space
410 call this%GLL_to_GL%map(this%tx, vx%x, nel, this%Xh_GL)
411 call this%GLL_to_GL%map(this%ty, vy%x, nel, this%Xh_GL)
412 call this%GLL_to_GL%map(this%tz, vz%x, nel, this%Xh_GL)
413
414 ! Map the scalar onto the high-order space
415 call this%GLL_to_GL%map(this%temp, s%x, nel, this%Xh_GL)
416
417 ! Compute the scalar gradient in the high-order space
418 call opgrad(this%vr, this%vs, this%vt, this%temp, c_gl)
419
420 ! Compute the convective term, i.e dot the velocity with the scalar grad
421 call vdot3(this%tbf, this%vr, this%vs, this%vt, &
422 this%tx, this%ty, this%tz, n_gl)
423
424 ! Map back to the original space (we reuse this%temp)
425 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
426
427 ! Update the source term
428 call sub2(fs%x, this%temp, n)
429
430 else
431 !$omp parallel do private (e, i, idx)
432 do e = 1, coef%msh%nelv
433 ! Map advecting velocity onto the higher-order space
434 call this%GLL_to_GL%map(vx_gl, vx%x(1,1,1,e), 1, this%Xh_GL)
435 call this%GLL_to_GL%map(vy_gl, vy%x(1,1,1,e), 1, this%Xh_GL)
436 call this%GLL_to_GL%map(vz_gl, vz%x(1,1,1,e), 1, this%Xh_GL)
437
438 ! Map scalar onto the higher-order space
439 call this%GLL_to_GL%map(s_gl, s%x(1,1,1,e), 1, this%Xh_GL)
440
441 ! Gradient of s in the higher-order space
442 call opgrad(dsdx, dsdy, dsdz, s_gl, c_gl, e, e)
443
444 ! vx * ds/dx + vy * ds/dy + vz * ds/dz for each point in the element
445 do i = 1, this%Xh_GL%lxyz
446 f_gl(i) = vx_gl(i)*dsdx(i) + vy_gl(i)*dsdy(i) + vz_gl(i)*dsdz(i)
447 end do
448
449 ! Map back the contructed operator to the original space
450 call this%GLL_to_GL%map(temp, f_gl, 1, this%Xh_GLL)
451
452 idx = (e-1)*this%Xh_GLL%lxyz + 1
453
454 call sub2(fs%x(idx, 1, 1, 1), temp, this%Xh_GLL%lxyz)
455 end do
456 !$omp end parallel do
457 end if
458 end associate
459
461
462
463 !!> Add the advection term in ALE framework.
464 !! @param this The object.
465 !! @param vx The x component of velocity.
466 !! @param vy The y component of velocity.
467 !! @param vz The z component of velocity.
468 !! @param wm_x The x component of mesh velocity.
469 !! @param wm_y The y component of mesh velocity.
470 !! @param wm_z The z component of mesh velocity.
471 !! @param fx The x component of source term.
472 !! @param fy The y component of source term.
473 !! @param fz The z component of source term.
474 !! @param Xh The function space.
475 !! @param coef The coefficients of the (Xh, mesh) pair.
476 !! @param n Typically the size of the mesh.
477 !! @param dt Current time-step, not required for this method.
478 !! Here, we compute: - div ( u_i * wm ).
479 !! Based on Ho, L.W. A Legendre spectral element method for simulation of incompressible
480 !! unsteady viscous free-surface flows.
481 !! Ph.D. thesis, Massachusetts Institute of Technology, 1989.
482 !! Note: In Nek5000, dealiasing is not done for this term.
483 subroutine compute_ale_advection_dealias(this, vx, vy, vz, wm_x, wm_y, wm_z, &
484 fx, fy, fz, Xh, coef, n, dt)
485 class(adv_dealias_t), intent(inout) :: this
486 type(field_t), intent(inout) :: vx, vy, vz
487 type(field_t), intent(inout) :: wm_x, wm_y, wm_z
488 type(field_t), intent(inout) :: fx, fy, fz
489 type(space_t), intent(in) :: Xh
490 type(coef_t), intent(in) :: coef
491 real(kind=rp), dimension(this%Xh_GL%lxyz) :: vx_gl, vy_gl, vz_gl
492 real(kind=rp), dimension(this%Xh_GL%lxyz) :: wm_x_gl, wm_y_gl, wm_z_gl
493 real(kind=rp), dimension(this%Xh_GL%lxyz) :: flux_gl
494 real(kind=rp), dimension(this%Xh_GL%lxyz) :: grad_x, grad_y, grad_z
495 real(kind=rp), dimension(this%Xh_GL%lxyz) :: total_div_gl
496 integer :: e, i, idx, nel, n_GL
497 real(kind=rp), dimension(this%Xh_GLL%lxyz) :: temp_x, temp_y, temp_z
498 integer, intent(in) :: n
499 real(kind=rp), intent(in), optional :: dt
500
501 nel = coef%msh%nelv
502 n_gl = nel * this%Xh_GL%lxyz
503
504 associate(c_gl => this%coef_GL)
505 if (neko_bcknd_device .eq. 1) then
506 call neko_error("ALE advection with dealiasing not " // &
507 "implemented yet for device")
508 else if ((neko_bcknd_sx .eq. 1) .or. (neko_bcknd_xsmm .eq. 1)) then
509 call neko_error("ALE advection with dealiasing not " // &
510 "implemented yet for device")
511 else
512 !$omp parallel do private(e, i, flux_GL, total_div_GL, idx)
513 do e = 1, coef%msh%nelv
514 ! Map advecting velocity and mesh velocity onto the higher-order space
515 call this%GLL_to_GL%map(vx_gl, vx%x(1,1,1,e), 1, this%Xh_GL)
516 call this%GLL_to_GL%map(vy_gl, vy%x(1,1,1,e), 1, this%Xh_GL)
517 call this%GLL_to_GL%map(vz_gl, vz%x(1,1,1,e), 1, this%Xh_GL)
518 call this%GLL_to_GL%map(wm_x_gl, wm_x%x(1,1,1,e), 1, this%Xh_GL)
519 call this%GLL_to_GL%map(wm_y_gl, wm_y%x(1,1,1,e), 1, this%Xh_GL)
520 call this%GLL_to_GL%map(wm_z_gl, wm_z%x(1,1,1,e), 1, this%Xh_GL)
521
522 ! x-momentum
523 total_div_gl = 0.0_rp
524 ! I think below can be written more efficiently. Will fix it later.
525 ! This works for now.
526
527 ! div(u * wm_*) = d/dx (u * wm_x) + d/dy (u * wm_y) + d/dz (u * wm_z)
528
529 flux_gl = vx_gl * wm_x_gl
530 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
531 total_div_gl = total_div_gl + grad_x
532 flux_gl = vx_gl * wm_y_gl
533 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
534 total_div_gl = total_div_gl + grad_y
535 flux_gl = vx_gl * wm_z_gl
536 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
537 total_div_gl = total_div_gl + grad_z
538
539 ! Map back the contructed operator to the original space
540 call this%GLL_to_GL%map(temp_x, total_div_gl, 1, this%Xh_GLL)
541
542 ! y-momentum
543 total_div_gl = 0.0_rp
544 ! div(v * wm_*) = d/dx (v * wm_x) + d/dy (v * wm_y) + d/dz (v * wm_z)
545
546 flux_gl = vy_gl * wm_x_gl
547 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
548 total_div_gl = total_div_gl + grad_x
549 flux_gl = vy_gl * wm_y_gl
550 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
551 total_div_gl = total_div_gl + grad_y
552 flux_gl = vy_gl * wm_z_gl
553 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
554 total_div_gl = total_div_gl + grad_z
555
556 ! Map back the contructed operator to the original space
557 call this%GLL_to_GL%map(temp_y, total_div_gl, 1, this%Xh_GLL)
558
559 ! z-momentum
560 total_div_gl = 0.0_rp
561 ! div(w * wm_*) = d/dx (w * wm_x) + d/dy (w * wm_y) + d/dz (w * wm_z)
562
563 flux_gl = vz_gl * wm_x_gl
564 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
565 total_div_gl = total_div_gl + grad_x
566 flux_gl = vz_gl * wm_y_gl
567 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
568 total_div_gl = total_div_gl + grad_y
569 flux_gl = vz_gl * wm_z_gl
570 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
571 total_div_gl = total_div_gl + grad_z
572
573 ! Map back the contructed operator to the original space
574 call this%GLL_to_GL%map(temp_z, total_div_gl, 1, this%Xh_GLL)
575
576 ! Note we add (+) here since the ALE advection term is
577 ! - div(u * wm) on the LHS. So on the RHS it will be + div(u * wm)
578
579 idx = (e-1)*this%Xh_GLL%lxyz+1
580 do concurrent(i = 0:this%Xh_GLL%lxyz-1)
581 fx%x(i+idx,1,1,1) = fx%x(i+idx,1,1,1) + temp_x(i+1)
582 fy%x(i+idx,1,1,1) = fy%x(i+idx,1,1,1) + temp_y(i+1)
583 fz%x(i+idx,1,1,1) = fz%x(i+idx,1,1,1) + temp_z(i+1)
584 end do
585 end do
586 !$omp end parallel do
587 end if
588 end associate
589
590 end subroutine compute_ale_advection_dealias
591
592 subroutine recompute_metrics_dealias(this, coef, moving_boundary)
593 class(adv_dealias_t), intent(inout) :: this
594 type(coef_t), intent(in) :: coef
595 logical, intent(in) :: moving_boundary
596 integer :: nel
597
598 if (.not. moving_boundary) return
599
600 nel = coef%msh%nelv
601 call this%GLL_to_GL%map(this%coef_GL%drdx, coef%drdx, nel, this%Xh_GL)
602 call this%GLL_to_GL%map(this%coef_GL%dsdx, coef%dsdx, nel, this%Xh_GL)
603 call this%GLL_to_GL%map(this%coef_GL%dtdx, coef%dtdx, nel, this%Xh_GL)
604
605 call this%GLL_to_GL%map(this%coef_GL%drdy, coef%drdy, nel, this%Xh_GL)
606 call this%GLL_to_GL%map(this%coef_GL%dsdy, coef%dsdy, nel, this%Xh_GL)
607 call this%GLL_to_GL%map(this%coef_GL%dtdy, coef%dtdy, nel, this%Xh_GL)
608
609 call this%GLL_to_GL%map(this%coef_GL%drdz, coef%drdz, nel, this%Xh_GL)
610 call this%GLL_to_GL%map(this%coef_GL%dsdz, coef%dsdz, nel, this%Xh_GL)
611 call this%GLL_to_GL%map(this%coef_GL%dtdz, coef%dtdz, nel, this%Xh_GL)
612
613 end subroutine recompute_metrics_dealias
614
615
616end module adv_dealias
Return the device pointer for an associated Fortran array.
Definition device.F90:107
Map a Fortran array to a device (allocate and associate)
Definition device.F90:77
Subroutines to add advection terms to the RHS of a transport equation.
subroutine init_dealias(this, lxd, coef)
Constructor.
subroutine compute_scalar_advection_dealias(this, vx, vy, vz, s, fs, xh, coef, n, dt)
Add the advection term for a scalar, i.e. , to the RHS.
subroutine free_dealias(this)
Destructor.
subroutine compute_advection_dealias(this, vx, vy, vz, fx, fy, fz, xh, coef, n, dt)
Add the advection term for the fluid, i.e. , to the RHS.
subroutine compute_ale_advection_dealias(this, vx, vy, vz, wm_x, wm_y, wm_z, fx, fy, fz, xh, coef, n, dt)
subroutine recompute_metrics_dealias(this, coef, moving_boundary)
Subroutines to add advection terms to the RHS of a transport equation.
Definition advection.f90:34
Coefficients.
Definition coef.f90:34
subroutine, public device_vdot3(dot_d, u1_d, u2_d, u3_d, v1_d, v2_d, v3_d, n, strm)
Compute a dot product (3-d version) assuming vector components etc.
subroutine, public device_sub2(a_d, b_d, n, strm)
Vector substraction .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
subroutine, public device_free(x_d)
Deallocate memory on the device.
Definition device.F90:225
Defines a field.
Definition field.f90:34
Routines to interpolate between different spaces.
Definition math.f90:60
subroutine, public vdot3(dot, u1, u2, u3, v1, v2, v3, n)
Compute a dot product (3-d version) assuming vector components etc.
Definition math.f90:685
subroutine, public sub2(a, b, n)
Vector substraction .
Definition math.f90:769
Build configurations.
integer, parameter neko_bcknd_sx
integer, parameter neko_bcknd_hip
integer, parameter neko_bcknd_device
integer, parameter neko_bcknd_opencl
integer, parameter neko_bcknd_cuda
integer, parameter neko_bcknd_xsmm
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Operators.
Definition operators.f90:34
subroutine, public opgrad(ux, uy, uz, u, coef, es, ee)
Compute the weak gradient of a scalar field, i.e. the gradient multiplied by the mass matrix.
Defines a function space.
Definition space.f90:34
integer, parameter, public gl
Definition space.f90:49
Utilities.
Definition utils.f90:35
Type encapsulating advection routines with dealiasing.
Base abstract type for computing the advection operator.
Definition advection.f90:46
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:62
Interpolation between two space::space_t.
The function space for the SEM solution fields.
Definition space.f90:63