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-2026, 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, tempx, tempy, tempz), &
314 !$omp& private(tx, ty, tz, vr, vs, vt, tfx, tfy, tfz)
315 do e = 1, coef%msh%nelv
316 call this%GLL_to_GL%map(tx, vx%x(1,1,1,e), 1, this%Xh_GL)
317 call this%GLL_to_GL%map(ty, vy%x(1,1,1,e), 1, this%Xh_GL)
318 call this%GLL_to_GL%map(tz, vz%x(1,1,1,e), 1, this%Xh_GL)
319
320 call opgrad(vr, vs, vt, tx, c_gl, e, e)
321 do i = 1, this%Xh_GL%lxyz
322 tfx(i) = tx(i)*vr(i) + ty(i)*vs(i) + tz(i)*vt(i)
323 end do
324
325 call opgrad(vr, vs, vt, ty, c_gl, e, e)
326 do i = 1, this%Xh_GL%lxyz
327 tfy(i) = tx(i)*vr(i) + ty(i)*vs(i) + tz(i)*vt(i)
328 end do
329
330 call opgrad(vr, vs, vt, tz, c_gl, e, e)
331 do i = 1, this%Xh_GL%lxyz
332 tfz(i) = tx(i)*vr(i) + ty(i)*vs(i) + tz(i)*vt(i)
333 end do
334
335 call this%GLL_to_GL%map(tempx, tfx, 1, this%Xh_GLL)
336 call this%GLL_to_GL%map(tempy, tfy, 1, this%Xh_GLL)
337 call this%GLL_to_GL%map(tempz, tfz, 1, this%Xh_GLL)
338
339 idx = (e-1)*this%Xh_GLL%lxyz+1
340 do concurrent(i = 0:this%Xh_GLL%lxyz-1)
341 fx%x(i+idx,1,1,1) = fx%x(i+idx,1,1,1) - tempx(i+1)
342 fy%x(i+idx,1,1,1) = fy%x(i+idx,1,1,1) - tempy(i+1)
343 fz%x(i+idx,1,1,1) = fz%x(i+idx,1,1,1) - tempz(i+1)
344 end do
345 end do
346 !$omp end parallel do
347 end if
348 end associate
349
350 end subroutine compute_advection_dealias
351
364 subroutine compute_scalar_advection_dealias(this, vx, vy, vz, s, fs, Xh, &
365 coef, n, dt)
366 class(adv_dealias_t), intent(inout) :: this
367 type(field_t), intent(inout) :: vx, vy, vz
368 type(field_t), intent(inout) :: s
369 type(field_t), intent(inout) :: fs
370 type(space_t), intent(in) :: Xh
371 type(coef_t), intent(in) :: coef
372 integer, intent(in) :: n
373 real(kind=rp), intent(in), optional :: dt
374
375 real(kind=rp), dimension(this%Xh_GL%lxyz) :: vx_gl, vy_gl, vz_gl, s_gl
376 real(kind=rp), dimension(this%Xh_GL%lxyz) :: dsdx, dsdy, dsdz
377 real(kind=rp), dimension(this%Xh_GL%lxyz) :: f_gl
378 integer :: e, i, idx, nel, n_GL
379 real(kind=rp), dimension(this%Xh_GLL%lxyz) :: temp
380
381 nel = coef%msh%nelv
382 n_gl = nel * this%Xh_GL%lxyz
383
384 associate(c_gl => this%coef_GL)
385 if (neko_bcknd_device .eq. 1) then
386
387 ! Map advecting velocity onto the higher-order space
388 call this%GLL_to_GL%map(this%tx, vx%x, nel, this%Xh_GL)
389 call this%GLL_to_GL%map(this%ty, vy%x, nel, this%Xh_GL)
390 call this%GLL_to_GL%map(this%tz, vz%x, nel, this%Xh_GL)
391
392 ! Map the scalar onto the high-order space
393 call this%GLL_to_GL%map(this%temp, s%x, nel, this%Xh_GL)
394
395 ! Compute the scalar gradient in the high-order space
396 call opgrad(this%vr, this%vs, this%vt, this%temp, c_gl)
397
398 ! Compute the convective term, i.e dot the velocity with the scalar grad
399 call device_vdot3(this%tbf_d, this%vr_d, this%vs_d, this%vt_d, &
400 this%tx_d, this%ty_d, this%tz_d, n_gl)
401
402 ! Map back to the original space (we reuse this%temp)
403 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
404
405 ! Update the source term
406 call device_sub2(fs%x_d, this%temp_d, n)
407
408 else if ((neko_bcknd_sx .eq. 1) .or. (neko_bcknd_xsmm .eq. 1)) then
409
410 ! Map advecting velocity onto the higher-order space
411 call this%GLL_to_GL%map(this%tx, vx%x, nel, this%Xh_GL)
412 call this%GLL_to_GL%map(this%ty, vy%x, nel, this%Xh_GL)
413 call this%GLL_to_GL%map(this%tz, vz%x, nel, this%Xh_GL)
414
415 ! Map the scalar onto the high-order space
416 call this%GLL_to_GL%map(this%temp, s%x, nel, this%Xh_GL)
417
418 ! Compute the scalar gradient in the high-order space
419 call opgrad(this%vr, this%vs, this%vt, this%temp, c_gl)
420
421 ! Compute the convective term, i.e dot the velocity with the scalar grad
422 call vdot3(this%tbf, this%vr, this%vs, this%vt, &
423 this%tx, this%ty, this%tz, n_gl)
424
425 ! Map back to the original space (we reuse this%temp)
426 call this%GLL_to_GL%map(this%temp, this%tbf, nel, this%Xh_GLL)
427
428 ! Update the source term
429 call sub2(fs%x, this%temp, n)
430
431 else
432 !$omp parallel do private (e, i, idx, vx_GL, vy_GL, s_GL, f_GL, temp)
433 do e = 1, coef%msh%nelv
434 ! Map advecting velocity onto the higher-order space
435 call this%GLL_to_GL%map(vx_gl, vx%x(1,1,1,e), 1, this%Xh_GL)
436 call this%GLL_to_GL%map(vy_gl, vy%x(1,1,1,e), 1, this%Xh_GL)
437 call this%GLL_to_GL%map(vz_gl, vz%x(1,1,1,e), 1, this%Xh_GL)
438
439 ! Map scalar onto the higher-order space
440 call this%GLL_to_GL%map(s_gl, s%x(1,1,1,e), 1, this%Xh_GL)
441
442 ! Gradient of s in the higher-order space
443 call opgrad(dsdx, dsdy, dsdz, s_gl, c_gl, e, e)
444
445 ! vx * ds/dx + vy * ds/dy + vz * ds/dz for each point in the element
446 do i = 1, this%Xh_GL%lxyz
447 f_gl(i) = vx_gl(i)*dsdx(i) + vy_gl(i)*dsdy(i) + vz_gl(i)*dsdz(i)
448 end do
449
450 ! Map back the contructed operator to the original space
451 call this%GLL_to_GL%map(temp, f_gl, 1, this%Xh_GLL)
452
453 idx = (e-1)*this%Xh_GLL%lxyz + 1
454
455 call sub2(fs%x(idx, 1, 1, 1), temp, this%Xh_GLL%lxyz)
456 end do
457 !$omp end parallel do
458 end if
459 end associate
460
462
463
464 !!> Add the advection term in ALE framework.
465 !! @param this The object.
466 !! @param vx The x component of velocity.
467 !! @param vy The y component of velocity.
468 !! @param vz The z component of velocity.
469 !! @param wm_x The x component of mesh velocity.
470 !! @param wm_y The y component of mesh velocity.
471 !! @param wm_z The z component of mesh velocity.
472 !! @param fx The x component of source term.
473 !! @param fy The y component of source term.
474 !! @param fz The z component of source term.
475 !! @param Xh The function space.
476 !! @param coef The coefficients of the (Xh, mesh) pair.
477 !! @param n Typically the size of the mesh.
478 !! @param dt Current time-step, not required for this method.
479 !! Here, we compute: - div ( u_i * wm ).
480 !! Based on Ho, L.W. A Legendre spectral element method for simulation of incompressible
481 !! unsteady viscous free-surface flows.
482 !! Ph.D. thesis, Massachusetts Institute of Technology, 1989.
483 !! Note: In Nek5000, dealiasing is not done for this term.
484 subroutine compute_ale_advection_dealias(this, vx, vy, vz, wm_x, wm_y, wm_z, &
485 fx, fy, fz, Xh, coef, n, dt)
486 class(adv_dealias_t), intent(inout) :: this
487 type(field_t), intent(inout) :: vx, vy, vz
488 type(field_t), intent(inout) :: wm_x, wm_y, wm_z
489 type(field_t), intent(inout) :: fx, fy, fz
490 type(space_t), intent(in) :: Xh
491 type(coef_t), intent(in) :: coef
492 real(kind=rp), dimension(this%Xh_GL%lxyz) :: vx_gl, vy_gl, vz_gl
493 real(kind=rp), dimension(this%Xh_GL%lxyz) :: wm_x_gl, wm_y_gl, wm_z_gl
494 real(kind=rp), dimension(this%Xh_GL%lxyz) :: flux_gl
495 real(kind=rp), dimension(this%Xh_GL%lxyz) :: grad_x, grad_y, grad_z
496 real(kind=rp), dimension(this%Xh_GL%lxyz) :: total_div_gl
497 integer :: e, i, idx, nel, n_GL
498 real(kind=rp), dimension(this%Xh_GLL%lxyz) :: temp_x, temp_y, temp_z
499 integer, intent(in) :: n
500 real(kind=rp), intent(in), optional :: dt
501
502 nel = coef%msh%nelv
503 n_gl = nel * this%Xh_GL%lxyz
504
505 associate(c_gl => this%coef_GL)
506 if (neko_bcknd_device .eq. 1) then
507 call neko_error("ALE advection with dealiasing not " // &
508 "implemented yet for device")
509 else if ((neko_bcknd_sx .eq. 1) .or. (neko_bcknd_xsmm .eq. 1)) then
510 call neko_error("ALE advection with dealiasing not " // &
511 "implemented yet for device")
512 else
513 !$omp parallel do private(e, i, flux_GL, total_div_GL, idx)
514 do e = 1, coef%msh%nelv
515 ! Map advecting velocity and mesh velocity onto the higher-order space
516 call this%GLL_to_GL%map(vx_gl, vx%x(1,1,1,e), 1, this%Xh_GL)
517 call this%GLL_to_GL%map(vy_gl, vy%x(1,1,1,e), 1, this%Xh_GL)
518 call this%GLL_to_GL%map(vz_gl, vz%x(1,1,1,e), 1, this%Xh_GL)
519 call this%GLL_to_GL%map(wm_x_gl, wm_x%x(1,1,1,e), 1, this%Xh_GL)
520 call this%GLL_to_GL%map(wm_y_gl, wm_y%x(1,1,1,e), 1, this%Xh_GL)
521 call this%GLL_to_GL%map(wm_z_gl, wm_z%x(1,1,1,e), 1, this%Xh_GL)
522
523 ! x-momentum
524 total_div_gl = 0.0_rp
525 ! I think below can be written more efficiently. Will fix it later.
526 ! This works for now.
527
528 ! div(u * wm_*) = d/dx (u * wm_x) + d/dy (u * wm_y) + d/dz (u * wm_z)
529
530 flux_gl = vx_gl * wm_x_gl
531 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
532 total_div_gl = total_div_gl + grad_x
533 flux_gl = vx_gl * wm_y_gl
534 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
535 total_div_gl = total_div_gl + grad_y
536 flux_gl = vx_gl * wm_z_gl
537 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
538 total_div_gl = total_div_gl + grad_z
539
540 ! Map back the contructed operator to the original space
541 call this%GLL_to_GL%map(temp_x, total_div_gl, 1, this%Xh_GLL)
542
543 ! y-momentum
544 total_div_gl = 0.0_rp
545 ! div(v * wm_*) = d/dx (v * wm_x) + d/dy (v * wm_y) + d/dz (v * wm_z)
546
547 flux_gl = vy_gl * wm_x_gl
548 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
549 total_div_gl = total_div_gl + grad_x
550 flux_gl = vy_gl * wm_y_gl
551 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
552 total_div_gl = total_div_gl + grad_y
553 flux_gl = vy_gl * wm_z_gl
554 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
555 total_div_gl = total_div_gl + grad_z
556
557 ! Map back the contructed operator to the original space
558 call this%GLL_to_GL%map(temp_y, total_div_gl, 1, this%Xh_GLL)
559
560 ! z-momentum
561 total_div_gl = 0.0_rp
562 ! div(w * wm_*) = d/dx (w * wm_x) + d/dy (w * wm_y) + d/dz (w * wm_z)
563
564 flux_gl = vz_gl * wm_x_gl
565 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
566 total_div_gl = total_div_gl + grad_x
567 flux_gl = vz_gl * wm_y_gl
568 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
569 total_div_gl = total_div_gl + grad_y
570 flux_gl = vz_gl * wm_z_gl
571 call opgrad(grad_x, grad_y, grad_z, flux_gl, c_gl, e, e)
572 total_div_gl = total_div_gl + grad_z
573
574 ! Map back the contructed operator to the original space
575 call this%GLL_to_GL%map(temp_z, total_div_gl, 1, this%Xh_GLL)
576
577 ! Note we add (+) here since the ALE advection term is
578 ! - div(u * wm) on the LHS. So on the RHS it will be + div(u * wm)
579
580 idx = (e-1)*this%Xh_GLL%lxyz+1
581 do concurrent(i = 0:this%Xh_GLL%lxyz-1)
582 fx%x(i+idx,1,1,1) = fx%x(i+idx,1,1,1) + temp_x(i+1)
583 fy%x(i+idx,1,1,1) = fy%x(i+idx,1,1,1) + temp_y(i+1)
584 fz%x(i+idx,1,1,1) = fz%x(i+idx,1,1,1) + temp_z(i+1)
585 end do
586 end do
587 !$omp end parallel do
588 end if
589 end associate
590
591 end subroutine compute_ale_advection_dealias
592
593 subroutine recompute_metrics_dealias(this, coef, moving_boundary)
594 class(adv_dealias_t), intent(inout) :: this
595 type(coef_t), intent(in) :: coef
596 logical, intent(in) :: moving_boundary
597 integer :: nel
598
599 if (.not. moving_boundary) return
600
601 nel = coef%msh%nelv
602 call this%GLL_to_GL%map(this%coef_GL%drdx, coef%drdx, nel, this%Xh_GL)
603 call this%GLL_to_GL%map(this%coef_GL%dsdx, coef%dsdx, nel, this%Xh_GL)
604 call this%GLL_to_GL%map(this%coef_GL%dtdx, coef%dtdx, nel, this%Xh_GL)
605
606 call this%GLL_to_GL%map(this%coef_GL%drdy, coef%drdy, nel, this%Xh_GL)
607 call this%GLL_to_GL%map(this%coef_GL%dsdy, coef%dsdy, nel, this%Xh_GL)
608 call this%GLL_to_GL%map(this%coef_GL%dtdy, coef%dtdy, nel, this%Xh_GL)
609
610 call this%GLL_to_GL%map(this%coef_GL%drdz, coef%drdz, nel, this%Xh_GL)
611 call this%GLL_to_GL%map(this%coef_GL%dsdz, coef%dsdz, nel, this%Xh_GL)
612 call this%GLL_to_GL%map(this%coef_GL%dtdz, coef%dtdz, nel, this%Xh_GL)
613
614 end subroutine recompute_metrics_dealias
615
616
617end 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:850
subroutine, public sub2(a, b, n)
Vector substraction .
Definition math.f90:946
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:63
Interpolation between two space::space_t.
The function space for the SEM solution fields.
Definition space.f90:63