Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
gradient_jump_penalty.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 utils, only : neko_error
39 use json_module, only : json_file
40 use math, only : add2, col2, col3, invcol2, add3, copy, absval
41 use point, only : point_t
42 use field, only : field_t
43 use dofmap, only : dofmap_t
45 use coefs, only : coef_t
46 use element, only : element_t
47 use hex, only : hex_t
48 use quad, only : quad_t
49 use gs_ops, only : gs_op_add
50 use space, only : space_t, gll
51 use gather_scatter, only : gs_t
57 use source_term, only : source_term_t
58 use field_list, only : field_list_t
59 use registry, only : neko_registry
60 use time_state, only : time_state_t
61 use operators, only : dudxyz
62 use, intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr
63
64 implicit none
65 private
66
69 type, public, extends(source_term_t):: gradient_jump_penalty_t
71 type(field_list_t) :: s_fields
73 type(field_t), pointer :: u
75 type(field_t), pointer :: v
77 type(field_t), pointer :: w
78
80 real(kind=rp) :: tau
82 integer :: p
84 integer :: lx
86 real(kind=rp), allocatable, dimension(:, :, :, :) :: penalty
87 type(c_ptr) :: penalty_d = c_null_ptr
89 real(kind=rp), allocatable, dimension(:, :, :, :) :: penalty_facet
90 type(c_ptr) :: penalty_facet_d = c_null_ptr
92 real(kind=rp), allocatable, dimension(:, :, :, :) :: grad1, &
93 grad2, grad3
94 type(c_ptr) :: grad1_d = c_null_ptr
95 type(c_ptr) :: grad2_d = c_null_ptr
96 type(c_ptr) :: grad3_d = c_null_ptr
98 real(kind=rp), allocatable, dimension(:, :, :, :) :: g
99 type(c_ptr) :: g_d = c_null_ptr
101 real(kind=rp), allocatable, dimension(:, :, :, :) :: flux1, flux2, flux3
102 type(c_ptr) :: flux1_d = c_null_ptr
103 type(c_ptr) :: flux2_d = c_null_ptr
104 type(c_ptr) :: flux3_d = c_null_ptr
106 real(kind=rp), allocatable, dimension(:, :, :, :) :: volflux1, &
107 volflux2, volflux3
108 type(c_ptr) :: volflux1_d = c_null_ptr
109 type(c_ptr) :: volflux2_d = c_null_ptr
110 type(c_ptr) :: volflux3_d = c_null_ptr
112 real(kind=rp), allocatable, dimension(:, :, :, :) :: absvolflux
113 type(c_ptr) :: absvolflux_d = c_null_ptr
115 real(kind=rp), allocatable, dimension(:, :, :, :) :: n1, n2, n3
116 type(c_ptr) :: n1_d = c_null_ptr
117 type(c_ptr) :: n2_d = c_null_ptr
118 type(c_ptr) :: n3_d = c_null_ptr
120 real(kind=rp), allocatable, dimension(:, :, :, :) :: facet_factor
121 type(c_ptr) :: facet_factor_d = c_null_ptr
123 integer, allocatable :: n_facet(:)
124 integer :: n_facet_max
126 real(kind=rp), allocatable, dimension(:, :, :, :) :: h2
128 real(kind=rp), allocatable :: dphidxi(:, :)
129 type(c_ptr) :: dphidxi_d = c_null_ptr
131 type(space_t) :: xh_gjp
132 type(dofmap_t) :: dm_gjp
133 type(gs_t) :: gs_gjp
135 integer :: n
137 integer :: n_large
138
139 contains
141 procedure, pass(this) :: init => gradient_jump_penalty_init
143 procedure, pass(this) :: init_from_components => &
146 procedure, pass(this) :: free => gradient_jump_penalty_free
148 procedure, pass(this) :: compute_single => &
151 procedure, pass(this) :: compute_ => gradient_jump_penalty_compute
152
154
155contains
162 subroutine gradient_jump_penalty_init(this, json, fields, coef, variable_name)
163 implicit none
164 class(gradient_jump_penalty_t), intent(inout) :: this
165 type(json_file), intent(inout) :: json
166 type(coef_t), target, intent(in) :: coef
167 character(len=*), intent(in) :: variable_name
168 type(field_list_t), intent(in), target :: fields
169
170 real(kind=rp) :: start_time, end_time
171 real(kind=rp) :: a, b
172
173 call json_get_or_default(json, "start_time", start_time, 0.0_rp)
174 call json_get_or_default(json, "end_time", end_time, huge(0.0_rp))
175
176 if ((coef%Xh%lx - 1) .eq. 1) then
177 call json_get_or_default(json, 'tau', a, 0.02_rp)
178 b = 0.0_rp
179 else
180 call json_get_or_default(json, 'scaling_factor', a, 0.8_rp)
181 call json_get_or_default(json, 'scaling_exponent', b, 4.0_rp)
182 end if
183
184 call this%init_from_components(coef, fields, start_time, end_time, a, b, &
185 variable_name)
186
187 end subroutine gradient_jump_penalty_init
188
196 subroutine gradient_jump_penalty_init_from_components(this, coef, fields, &
197 start_time, end_time, a, b, variable_name)
198 class(gradient_jump_penalty_t), intent(inout) :: this
199 type(coef_t), target, intent(in) :: coef
200 type(field_list_t), intent(in), target :: fields
201 real(kind=rp), intent(in) :: start_time
202 real(kind=rp), intent(in) :: end_time
203 real(kind=rp), intent(in) :: a, b
204 character(len=*), intent(in) :: variable_name
205
206 integer :: i, j, k, l
207 real(kind=rp), allocatable :: zg(:) ! Quadrature points
208 real(kind=rp) :: normal(3)
209
210 ! Here, and in facet_factor_init() and dist2_quadrature_hex() below
211 call coef%require_facets('gradient_jump_penalty')
212
213 call this%free()
214
215 call this%init_base(fields, coef, start_time, end_time)
216
217 this%u => neko_registry%get_field("u")
218 this%v => neko_registry%get_field("v")
219 this%w => neko_registry%get_field("w")
220
221 if (fields%size() .eq. 1) then
222 call this%s_fields%init(1)
223 call this%s_fields%assign(1, &
224 neko_registry%get_field(variable_name))
225 else if (fields%size() .eq. 3) then
226 call this%s_fields%init(3)
227 call this%s_fields%assign(1, this%u)
228 call this%s_fields%assign(2, this%v)
229 call this%s_fields%assign(3, this%w)
230 else
231 call neko_error("The GJP source assumes either 3 or 1 RHS fields.")
232 end if
233
234
235
236
237 this%p = coef%dof%Xh%lx - 1
238 this%lx = coef%dof%Xh%lx
239
240 if (this%p .gt. 1) then
241 this%tau = -a * (this%p + 1) ** (-b)
242 else
243 this%tau = -a
244 end if
245
246 this%n = this%lx ** 3 * this%coef%msh%nelv
247 this%n_large = (this%lx + 2) ** 3 * this%coef%msh%nelv
248
249 allocate(this%n_facet(this%coef%msh%nelv))
250 do i = 1, this%coef%msh%nelv
251 select type (ep => this%coef%msh%elements(i)%e)
252 type is (hex_t)
253 this%n_facet(i) = 6
254 type is (quad_t)
255 call neko_error("Only Hexahedral element is &
256 &supported now for gradient jump penalty")
257 end select
258 end do
259 this%n_facet_max = maxval(this%n_facet)
260
261 allocate(this%h2(this%lx + 2, this%lx + 2, &
262 this%lx + 2, this%coef%msh%nelv))
263
264 do i = 1, this%coef%msh%nelv
265 select type (ep => this%coef%msh%elements(i)%e)
266 type is (hex_t)
267 call eval_h2_hex(this%h2(:, :, :, i), this%lx, i, this%coef)
268 type is (quad_t)
269 call neko_error("Gradient jump penalty error: mesh size &
270 &evaluation is not supported for quad_t")
271 end select
272 end do
273
274 allocate(zg(this%lx))
275 allocate(this%dphidxi(this%lx, this%lx))
276
277 zg = coef%Xh%zg(:,1)
278 do i = 1, coef%Xh%lx
279 do j = 1, coef%Xh%lx
280 this%dphidxi(j,i) = this%coef%Xh%dx(j,i)
281 end do
282 end do
283
284 allocate(this%penalty(this%lx, this%lx, this%lx, this%coef%msh%nelv))
285 allocate(this%grad1(this%lx, this%lx, this%lx, this%coef%msh%nelv))
286 allocate(this%grad2(this%lx, this%lx, this%lx, this%coef%msh%nelv))
287 allocate(this%grad3(this%lx, this%lx, this%lx, this%coef%msh%nelv))
288
289 allocate(this%penalty_facet(this%lx + 2, this%lx + 2, &
290 this%lx + 2, this%coef%msh%nelv))
291 allocate(this%G(this%lx + 2, this%lx + 2, &
292 this%lx + 2, this%coef%msh%nelv))
293 allocate(this%flux1(this%lx + 2, this%lx + 2, &
294 this%lx + 2, this%coef%msh%nelv))
295 allocate(this%flux2(this%lx + 2, this%lx + 2, &
296 this%lx + 2, this%coef%msh%nelv))
297 allocate(this%flux3(this%lx + 2, this%lx + 2, &
298 this%lx + 2, this%coef%msh%nelv))
299 allocate(this%volflux1(this%lx + 2, this%lx + 2, &
300 this%lx + 2, this%coef%msh%nelv))
301 allocate(this%volflux2(this%lx + 2, this%lx + 2, &
302 this%lx + 2, this%coef%msh%nelv))
303 allocate(this%volflux3(this%lx + 2, this%lx + 2, &
304 this%lx + 2, this%coef%msh%nelv))
305 allocate(this%absvolflux(this%lx + 2, this%lx + 2, &
306 this%lx + 2, this%coef%msh%nelv))
307 allocate(this%n1(this%lx + 2, this%lx + 2, &
308 this%lx + 2, this%coef%msh%nelv))
309 allocate(this%n2(this%lx + 2, this%lx + 2, &
310 this%lx + 2, this%coef%msh%nelv))
311 allocate(this%n3(this%lx + 2, this%lx + 2, &
312 this%lx + 2, this%coef%msh%nelv))
313
314 ! Extract facets' normals
315 do i = 1, this%coef%msh%nelv
316 do j = 1, 6 ! for hexahedral elements
317 do k = 1, this%lx
318 do l = 1, this%lx
319 select case (j)
320 case (1)
321 normal = this%coef%get_normal(1, l, k, i, j)
322 this%n1(1, l + 1, k + 1, i) = normal(1)
323 this%n2(1, l + 1, k + 1, i) = normal(2)
324 this%n3(1, l + 1, k + 1, i) = normal(3)
325 case (2)
326 normal = this%coef%get_normal(1, l, k, i, j)
327 this%n1(this%lx + 2, l + 1, k + 1, i) = normal(1)
328 this%n2(this%lx + 2, l + 1, k + 1, i) = normal(2)
329 this%n3(this%lx + 2, l + 1, k + 1, i) = normal(3)
330 case (3)
331 normal = this%coef%get_normal(l, 1, k, i, j)
332 this%n1(l + 1, 1, k + 1, i) = normal(1)
333 this%n2(l + 1, 1, k + 1, i) = normal(2)
334 this%n3(l + 1, 1, k + 1, i) = normal(3)
335 case (4)
336 normal = this%coef%get_normal(l, 1, k, i, j)
337 this%n1(l + 1, this%lx + 2, k + 1, i) = normal(1)
338 this%n2(l + 1, this%lx + 2, k + 1, i) = normal(2)
339 this%n3(l + 1, this%lx + 2, k + 1, i) = normal(3)
340 case (5)
341 normal = this%coef%get_normal(l, k, 1, i, j)
342 this%n1(l + 1, k + 1, 1, i) = normal(1)
343 this%n2(l + 1, k + 1, 1, i) = normal(2)
344 this%n3(l + 1, k + 1, 1, i) = normal(3)
345 case (6)
346 normal = this%coef%get_normal(l, k, 1, i, j)
347 this%n1(l + 1, k + 1, this%lx + 2, i) = normal(1)
348 this%n2(l + 1, k + 1, this%lx + 2, i) = normal(2)
349 this%n3(l + 1, k + 1, this%lx + 2, i) = normal(3)
350 case default
351 call neko_error("The face index is not correct")
352 end select
353 end do
354 end do
355 end do
356 end do
357
358 ! Assemble facet factor
359 call facet_factor_init(this)
360
361 ! Initialize Gather-Scatter
362 call this%Xh_GJP%init(gll, this%lx+2, this%lx+2, this%lx+2)
363 call this%dm_GJP%init(this%coef%msh, this%Xh_GJP)
364 call this%gs_GJP%init(this%dm_GJP)
365
366 ! Initialize pointers for device
367 if (neko_bcknd_device .eq. 1) then
368 call device_map(this%dphidxi, this%dphidxi_d, &
369 this%lx * this%lx)
370 call device_map(this%penalty, this%penalty_d, this%n)
371 call device_map(this%grad1, this%grad1_d, this%n)
372 call device_map(this%grad2, this%grad2_d, this%n)
373 call device_map(this%grad3, this%grad3_d, this%n)
374
375 call device_map(this%penalty_facet, this%penalty_facet_d, this%n_large)
376 call device_map(this%G, this%G_d, this%n_large)
377 call device_map(this%flux1, this%flux1_d, this%n_large)
378 call device_map(this%flux2, this%flux2_d, this%n_large)
379 call device_map(this%flux3, this%flux3_d, this%n_large)
380
381 call device_map(this%volflux1, this%volflux1_d, this%n_large)
382 call device_map(this%volflux2, this%volflux2_d, this%n_large)
383 call device_map(this%volflux3, this%volflux3_d, this%n_large)
384 call device_map(this%absvolflux, this%absvolflux_d, this%n_large)
385
386 call device_map(this%n1, this%n1_d, this%n_large)
387 call device_map(this%n2, this%n2_d, this%n_large)
388 call device_map(this%n3, this%n3_d, this%n_large)
389 call device_map(this%facet_factor, this%facet_factor_d, this%n_large)
390
391 call device_memcpy(this%dphidxi, this%dphidxi_d, &
392 this%lx * this%lx, &
393 host_to_device, sync = .false.)
394 call device_memcpy(this%n1, this%n1_d, this%n_large, &
395 host_to_device, sync = .false.)
396 call device_memcpy(this%n2, this%n2_d, this%n_large, &
397 host_to_device, sync = .false.)
398 call device_memcpy(this%n3, this%n3_d, this%n_large, &
399 host_to_device, sync = .false.)
400 call device_memcpy(this%facet_factor, this%facet_factor_d, this%n_large,&
401 host_to_device, sync = .false.)
402
403 end if
404
406
410 subroutine eval_h2_hex(h2_el, n, i, coef)
411 integer, intent(in) :: n, i
412 type(coef_t), pointer, intent(in) :: coef
413 real(kind=rp), intent(inout) :: h2_el(n + 2, n + 2, n + 2)
414
415 type(dofmap_t), pointer :: dm
416 integer :: j, k, l
417
418 dm => coef%dof
419
420 h2_el = 0.0_rp
421
422 do j = 1, 6
423 do k = 1, n
424 do l = 1, n
425 select case (j)
426 case (1)
427 h2_el(1, l + 1, k + 1) = &
428 dist2_quadrature_hex(l, k, j, i, n, dm, coef)
429 case (2)
430 h2_el(n + 2, l + 1, k + 1) = &
431 dist2_quadrature_hex(l, k, j, i, n, dm, coef)
432 case (3)
433 h2_el(l + 1, 1, k + 1) = &
434 dist2_quadrature_hex(l, k, j, i, n, dm, coef)
435 case (4)
436 h2_el(l + 1, n + 2, k + 1) = &
437 dist2_quadrature_hex(l, k, j, i, n, dm, coef)
438 case (5)
439 h2_el(l + 1, k + 1, 1) = &
440 dist2_quadrature_hex(l, k, j, i, n, dm, coef)
441 case (6)
442 h2_el(l + 1, k + 1, n + 2) = &
443 dist2_quadrature_hex(l, k, j, i, n, dm, coef)
444 case default
445 call neko_error("The face index is not correct")
446 end select
447 end do
448 end do
449 end do
450
451 end subroutine eval_h2_hex
452
453 function dist2_quadrature_hex(l, k, j, i, n, dm, coef) result(dist2)
454 integer, intent(in) :: l, k, j, i, n
455 type(dofmap_t), pointer, intent(in) :: dm
456 type(coef_t), pointer, intent(in) :: coef
457 real(kind=rp) :: dist2, dist_1, dist_2
458
459 real(kind=rp) :: x1, y1, z1, x2, y2, z2
460 real(kind=rp) :: normal1(3), normal2(3)
461 real(kind=rp) :: n11, n12, n13, n21, n22, n23
462 real(kind=rp) :: v1, v2, v3
463
464 dist2 = 0.0_rp
465 select case (j)
466 case (1)
467 normal1 = coef%get_normal(1, l, k, i, 1)
468 n11 = normal1(1)
469 n12 = normal1(2)
470 n13 = normal1(3)
471 x1 = dm%x(1, l, k, i)
472 y1 = dm%y(1, l, k, i)
473 z1 = dm%z(1, l, k, i)
474 normal2 = coef%get_normal(1, l, k, i, 2)
475 n21 = normal2(1)
476 n22 = normal2(2)
477 n23 = normal2(3)
478 x2 = dm%x(n, l, k, i)
479 y2 = dm%y(n, l, k, i)
480 z2 = dm%z(n, l, k, i)
481 case (2)
482 ! now the facet pair share the same value for h
483 ! but just let it be here for furture possible changes
484 normal1 = coef%get_normal(1, l, k, i, 2)
485 n11 = normal1(1)
486 n12 = normal1(2)
487 n13 = normal1(3)
488 x1 = dm%x(n, l, k, i)
489 y1 = dm%y(n, l, k, i)
490 z1 = dm%z(n, l, k, i)
491 normal2 = coef%get_normal(1, l, k, i, 1)
492 n21 = normal2(1)
493 n22 = normal2(2)
494 n23 = normal2(3)
495 x2 = dm%x(1, l, k, i)
496 y2 = dm%y(1, l, k, i)
497 z2 = dm%z(1, l, k, i)
498 case (3)
499 normal1 = coef%get_normal(1, l, k, i, 3)
500 n11 = normal1(1)
501 n12 = normal1(2)
502 n13 = normal1(3)
503 x1 = dm%x(l, 1, k, i)
504 y1 = dm%y(l, 1, k, i)
505 z1 = dm%z(l, 1, k, i)
506 normal2 = coef%get_normal(1, l, k, i, 4)
507 n21 = normal2(1)
508 n22 = normal2(2)
509 n23 = normal2(3)
510 x2 = dm%x(l, n, k, i)
511 y2 = dm%y(l, n, k, i)
512 z2 = dm%z(l, n, k, i)
513 case (4)
514 normal1 = coef%get_normal(1, l, k, i, 4)
515 n11 = normal1(1)
516 n12 = normal1(2)
517 n13 = normal1(3)
518 x1 = dm%x(l, n, k, i)
519 y1 = dm%y(l, n, k, i)
520 z1 = dm%z(l, n, k, i)
521 normal2 = coef%get_normal(1, l, k, i, 3)
522 n21 = normal2(1)
523 n22 = normal2(2)
524 n23 = normal2(3)
525 x2 = dm%x(l, 1, k, i)
526 y2 = dm%y(l, 1, k, i)
527 z2 = dm%z(l, 1, k, i)
528 case (5)
529 normal1 = coef%get_normal(1, l, k, i, 5)
530 n11 = normal1(1)
531 n12 = normal1(2)
532 n13 = normal1(3)
533 x1 = dm%x(l, k, 1, i)
534 y1 = dm%y(l, k, 1, i)
535 z1 = dm%z(l, k, 1, i)
536 normal2 = coef%get_normal(1, l, k, i, 6)
537 n21 = normal2(1)
538 n22 = normal2(2)
539 n23 = normal2(3)
540 x2 = dm%x(l, k, n, i)
541 y2 = dm%y(l, k, n, i)
542 z2 = dm%z(l, k, n, i)
543 case (6)
544 normal1 = coef%get_normal(1, l, k, i, 6)
545 n11 = normal1(1)
546 n12 = normal1(2)
547 n13 = normal1(3)
548 x1 = dm%x(l, k, n, i)
549 y1 = dm%y(l, k, n, i)
550 z1 = dm%z(l, k, n, i)
551 normal2 = coef%get_normal(1, l, k, i, 5)
552 n21 = normal2(1)
553 n22 = normal2(2)
554 n23 = normal2(3)
555 x2 = dm%x(l, k, 1, i)
556 y2 = dm%y(l, k, 1, i)
557 z2 = dm%z(l, k, 1, i)
558 case default
559 call neko_error("The face index is not correct")
560 end select
561
562 ! get the vector from the quadrature point to the one on the other side
563 v1 = x2 - x1
564 v2 = y2 - y1
565 v3 = z2 - z1
566 ! Project onto tabsvolflhe facet-normal direction of the point
567 dist_1 = v1*n11 + v2*n12 + v3*n13
568 dist_2 = - (v1*n21 + v2*n22 + v3*n23)
569
570 dist2 = ((dist_1 + dist_2)/2.0_rp)*((dist_1 + dist_2)/2.0_rp)
571
572 end function dist2_quadrature_hex
573
575 subroutine facet_factor_init(this)
576 class(gradient_jump_penalty_t), intent(inout) :: this
577 integer :: i, j, k, l
578 real(kind=rp) :: area_tmp
579
580 allocate(this%facet_factor(this%lx + 2, this%lx + 2, &
581 this%lx + 2, this%coef%msh%nelv))
582
583 associate(facet_factor => this%facet_factor, &
584 coef => this%coef, &
585 lx => this%lx, &
586 nelv => this%coef%msh%nelv, &
587 jacinv => this%coef%jacinv, h2 => this%h2, &
588 tau => this%tau, n1 => this%n1, &
589 n2 => this%n2, n3 => this%n3)
590
591 do i = 1, nelv
592 do j = 1, 6 ! for hexahedral elementsh2
593 do k = 1, lx
594 do l = 1, lx
595 select case (j)
596 case (1)
597 area_tmp = coef%get_area(1, l, k, i, j)
598 facet_factor(1, l + 1, k + 1, i) = area_tmp * tau * &
599 h2(1, l + 1, k + 1, i) * &
600 (n1(1, l + 1, k + 1, i) * coef%drdx(1, l, k, i) + &
601 n2(1, l + 1, k + 1, i) * coef%drdy(1, l, k, i) + &
602 n3(1, l + 1, k + 1, i) * coef%drdz(1, l, k, i) ) &
603 * jacinv(1, l, k, i)
604 case (2)
605 area_tmp = coef%get_area(1, l, k, i, j)
606 facet_factor(lx + 2, l + 1, k + 1, i) = area_tmp * tau * &
607 h2(lx + 2, l + 1, k + 1, i) * &
608 (n1(lx + 2, l + 1, k + 1, i) * &
609 coef%drdx(lx, l, k, i) + &
610 n2(lx + 2, l + 1, k + 1, i) * &
611 coef%drdy(lx, l, k, i) + &
612 n3(lx + 2, l + 1, k + 1, i) * &
613 coef%drdz(lx, l, k, i) ) &
614 * jacinv(lx, l, k, i)
615 case (3)
616 area_tmp = coef%get_area(l, 1, k, i, j)
617 facet_factor(l + 1, 1, k + 1, i) = area_tmp * tau * &
618 h2(l + 1, 1, k + 1, i) * &
619 (n1(l + 1, 1, k + 1, i) * coef%dsdx(l, 1, k, i) + &
620 n2(l + 1, 1, k + 1, i) * coef%dsdy(l, 1, k, i) + &
621 n3(l + 1, 1, k + 1, i) * coef%dsdz(l, 1, k, i) ) &
622 * jacinv(l, 1, k, i)
623 case (4)
624 area_tmp = coef%get_area(l, 1, k, i, j)
625 facet_factor(l + 1, lx + 2, k + 1, i) = area_tmp * tau * &
626 h2(l + 1, lx + 2, k + 1, i) * &
627 (n1(l + 1, lx + 2, k + 1, i) * &
628 coef%dsdx(l, lx, k, i) + &
629 n2(l + 1, lx + 2, k + 1, i) * &
630 coef%dsdy(l, lx, k, i) + &
631 n3(l + 1, lx + 2, k + 1, i) * &
632 coef%dsdz(l, lx, k, i) ) &
633 * jacinv(l, lx, k, i)
634 case (5)
635 area_tmp = coef%get_area(l, k, 1, i, j)
636 facet_factor(l + 1, k + 1, 1, i) = area_tmp * tau * &
637 h2(l + 1, k + 1, 1, i) * &
638 (n1(l + 1, k + 1, 1, i) * coef%dtdx(l, k, 1, i) + &
639 n2(l + 1, k + 1, 1, i) * coef%dtdy(l, k, 1, i) + &
640 n3(l + 1, k + 1, 1, i) * coef%dtdz(l, k, 1, i) ) &
641 * jacinv(l, k, 1, i)
642 case (6)
643 area_tmp = coef%get_area(l, k, 1, i, j)
644 facet_factor(l + 1, k + 1, lx + 2, i) = area_tmp * tau * &
645 h2(l + 1, k + 1, lx + 2, i) * &
646 ( &
647 n1(l + 1, k + 1, lx + 2, i) * &
648 coef%dtdx(l, k, lx, i) + &
649 n2(l + 1, k + 1, lx + 2, i) * &
650 coef%dtdy(l, k, lx, i) + &
651 n3(l + 1, k + 1, lx + 2, i) * &
652 coef%dtdz(l, k, lx, i) &
653 ) &
654 * jacinv(l, k, lx, i)
655 case default
656 call neko_error("The face index is not correct")
657 end select
658 end do
659 end do
660 end do
661 end do
662
663 end associate
664 end subroutine facet_factor_init
665
668 implicit none
669 class(gradient_jump_penalty_t), intent(inout) :: this
670
671 call this%free_base
672
673 if (allocated(this%penalty)) then
674 if (neko_bcknd_device .eq. 1) then
675 call device_unmap(this%penalty, this%penalty_d)
676 end if
677 deallocate(this%penalty)
678 end if
679 if (allocated(this%grad1)) then
680 if (neko_bcknd_device .eq. 1) then
681 call device_unmap(this%grad1, this%grad1_d)
682 end if
683 deallocate(this%grad1)
684 end if
685 if (allocated(this%grad2)) then
686 if (neko_bcknd_device .eq. 1) then
687 call device_unmap(this%grad2, this%grad2_d)
688 end if
689 deallocate(this%grad2)
690 end if
691 if (allocated(this%grad3)) then
692 if (neko_bcknd_device .eq. 1) then
693 call device_unmap(this%grad3, this%grad3_d)
694 end if
695 deallocate(this%grad3)
696 end if
697 if (allocated(this%h2)) then
698 deallocate(this%h2)
699 end if
700 if (allocated(this%n_facet)) then
701 deallocate(this%n_facet)
702 end if
703 if (allocated(this%dphidxi)) then
704 if (neko_bcknd_device .eq. 1) then
705 call device_unmap(this%dphidxi, this%dphidxi_d)
706 end if
707 deallocate(this%dphidxi)
708 end if
709 if (allocated(this%penalty_facet)) then
710 if (neko_bcknd_device .eq. 1) then
711 call device_unmap(this%penalty_facet, this%penalty_facet_d)
712 end if
713 deallocate(this%penalty_facet)
714 end if
715 if (allocated(this%G)) then
716 if (neko_bcknd_device .eq. 1) then
717 call device_unmap(this%G, this%G_d)
718 end if
719 deallocate(this%G)
720 end if
721 if (allocated(this%flux1)) then
722 if (neko_bcknd_device .eq. 1) then
723 call device_unmap(this%flux1, this%flux1_d)
724 end if
725 deallocate(this%flux1)
726 end if
727 if (allocated(this%flux2)) then
728 if (neko_bcknd_device .eq. 1) then
729 call device_unmap(this%flux2, this%flux2_d)
730 end if
731 deallocate(this%flux2)
732 end if
733 if (allocated(this%flux3)) then
734 if (neko_bcknd_device .eq. 1) then
735 call device_unmap(this%flux3, this%flux3_d)
736 end if
737 deallocate(this%flux3)
738 end if
739 if (allocated(this%volflux1)) then
740 if (neko_bcknd_device .eq. 1) then
741 call device_unmap(this%volflux1, this%volflux1_d)
742 end if
743 deallocate(this%volflux1)
744 end if
745 if (allocated(this%volflux2)) then
746 if (neko_bcknd_device .eq. 1) then
747 call device_unmap(this%volflux2, this%volflux2_d)
748 end if
749 deallocate(this%volflux2)
750 end if
751 if (allocated(this%volflux3)) then
752 if (neko_bcknd_device .eq. 1) then
753 call device_unmap(this%volflux3, this%volflux3_d)
754 end if
755 deallocate(this%volflux3)
756 end if
757 if (allocated(this%absvolflux)) then
758 if (neko_bcknd_device .eq. 1) then
759 call device_unmap(this%absvolflux, this%absvolflux_d)
760 end if
761 deallocate(this%absvolflux)
762 end if
763 if (allocated(this%n1)) then
764 if (neko_bcknd_device .eq. 1) then
765 call device_unmap(this%n1, this%n1_d)
766 end if
767 deallocate(this%n1)
768 end if
769 if (allocated(this%n2)) then
770 if (neko_bcknd_device .eq. 1) then
771 call device_unmap(this%n2, this%n2_d)
772 end if
773 deallocate(this%n2)
774 end if
775 if (allocated(this%n3)) then
776 if (neko_bcknd_device .eq. 1) then
777 call device_unmap(this%n3, this%n3_d)
778 end if
779 deallocate(this%n3)
780 end if
781 if (allocated(this%facet_factor)) then
782 if (neko_bcknd_device .eq. 1) then
783 call device_unmap(this%facet_factor, this%facet_factor_d)
784 end if
785 deallocate(this%facet_factor)
786 end if
787
788 nullify(this%u)
789 nullify(this%v)
790 nullify(this%w)
791
792 call this%s_fields%free()
793
794 call this%Xh_GJP%free()
795 call this%gs_GJP%free()
796 call this%dm_GJP%free()
797
798 end subroutine gradient_jump_penalty_free
799
803 class(gradient_jump_penalty_t), intent(inout) :: this
804 type(field_t), intent(in) :: s
805
806 class(element_t), pointer :: ep
807 integer :: i
808
809 call g_compute(this, s)
810 call absvolflux_compute(this, this%u, this%v, this%w)
811
812 if (neko_bcknd_device .eq. 1) then
813 call device_col3(this%penalty_facet_d, this%absvolflux_d, this%G_d, &
814 this%n_large)
815 call device_col2(this%penalty_facet_d, this%facet_factor_d, this%n_large)
816 call device_gradient_jump_penalty_finalize(this%penalty_d, &
817 this%penalty_facet_d, &
818 this%dphidxi_d, &
819 this%lx, this%coef%msh%nelv)
820 else
821 call col3(this%penalty_facet, this%absvolflux, this%G, this%n_large)
822 call col2(this%penalty_facet, this%facet_factor, this%n_large)
823 call gradient_jump_penalty_finalize(this%penalty, this%penalty_facet, &
824 this%dphidxi, &
825 this%lx, this%coef%msh%nelv)
826 end if
827
829
832 subroutine gradient_jump_penalty_compute(this, time)
833 class(gradient_jump_penalty_t), intent(inout) :: this
834 type(time_state_t), intent(in) :: time
835 integer :: i, n_fields, n
836
837 n_fields = this%fields%size()
838 n = this%coef%dof%size()
839
840
841
842 do i = 1, n_fields
843
844 call this%compute_single(this%s_fields%items(i)%ptr)
845
846 if (neko_bcknd_device .eq. 1) then
847 call device_invcol2(this%penalty_d, this%coef%B_d, n)
848 call device_add2(this%fields%x_d(i), this%penalty_d, n)
849 else
850 call invcol2(this%penalty, this%coef%B, n)
851 call add2(this%fields%items(i)%ptr%x, this%penalty, n)
852 end if
853 end do
854
855 end subroutine gradient_jump_penalty_compute
856
864 subroutine gradient_jump_penalty_finalize(penalty, wa, dphidxi, lx, nelv)
865 integer, intent(in) :: lx, nelv
866 real(kind=rp), intent(inout) :: penalty(lx, lx, lx, nelv)
867 real(kind=rp), intent(in) :: wa(lx + 2, lx + 2, lx + 2, nelv)
868 real(kind=rp), intent(in) :: dphidxi(lx, lx)
869
870 call gradient_jump_penalty_finalize_hex(penalty, wa, dphidxi, lx, nelv)
871
872 end subroutine gradient_jump_penalty_finalize
873
881 subroutine gradient_jump_penalty_finalize_hex(penalty, wa, dphidxi, lx, nelv)
882 integer, intent(in) :: lx, nelv
883 real(kind=rp), intent(inout) :: penalty(lx, lx, lx, nelv)
884 real(kind=rp), intent(in) :: wa(lx + 2, lx + 2, lx + 2, nelv)
885 real(kind=rp), intent(in) :: dphidxi(lx, lx)
886
887 integer :: e, i, j, k
888
889 !$omp parallel do private(e, i, j, k)
890 do e = 1, nelv
891 do k = 1, lx
892 do j = 1, lx
893 !OCL NORECURRENCE, NOVREC, NOALIAS
894 !DIR$ CONCURRENT
895 !DIR$ IVDEP
896 !GCC$ ivdep
897 do i = 1, lx
898 penalty(i, j, k, e) = &
899 wa(1, j + 1, k + 1, e) * &
900 dphidxi(1, i) + &
901 wa(lx + 2, j + 1, k + 1, e) * &
902 dphidxi(lx, i) + &
903 wa(i + 1, 1, k + 1, e) * &
904 dphidxi(1, j) + &
905 wa(i + 1, lx + 2, k + 1, e) * &
906 dphidxi(lx, j) + &
907 wa(i + 1, j + 1, 1, e) * &
908 dphidxi(1, k) + &
909 wa(i + 1, j + 1, lx + 2, e) * &
910 dphidxi(lx, k)
911 end do
912 end do
913 end do
914 end do
915 !$omp end parallel do
916
918
921 subroutine g_compute(this, s)
922 class(gradient_jump_penalty_t), intent(inout) :: this
923 type(field_t), intent(in) :: s
924
925 call dudxyz(this%grad1, s%x, this%coef%drdx, &
926 this%coef%dsdx, this%coef%dtdx, this%coef)
927 call dudxyz(this%grad2, s%x, this%coef%drdy, &
928 this%coef%dsdy, this%coef%dtdy, this%coef)
929 call dudxyz(this%grad3, s%x, this%coef%drdz, &
930 this%coef%dsdz, this%coef%dtdz, this%coef)
931
932 if (neko_bcknd_device .eq. 1) then
933 call device_pick_facet_value_hex(this%flux1_d, this%grad1_d, &
934 this%lx, this%coef%msh%nelv)
935 call device_pick_facet_value_hex(this%flux2_d, this%grad2_d, &
936 this%lx, this%coef%msh%nelv)
937 call device_pick_facet_value_hex(this%flux3_d, this%grad3_d, &
938 this%lx, this%coef%msh%nelv)
939 call device_col2(this%flux1_d, this%n1_d, this%n_large)
940 call device_col2(this%flux2_d, this%n2_d, this%n_large)
941 call device_col2(this%flux3_d, this%n3_d, this%n_large)
942 call device_add3s2(this%G_d, this%flux1_d, this%flux2_d, &
943 1.0_rp, 1.0_rp, this%n_large)
944 call device_add2(this%G_d, this%flux3_d, this%n_large)
945 else
946 call pick_facet_value_hex(this%flux1, this%grad1, &
947 this%lx, this%coef%msh%nelv)
948 call pick_facet_value_hex(this%flux2, this%grad2, &
949 this%lx, this%coef%msh%nelv)
950 call pick_facet_value_hex(this%flux3, this%grad3, &
951 this%lx, this%coef%msh%nelv)
952 call col2(this%flux1, this%n1, this%n_large)
953 call col2(this%flux2, this%n2, this%n_large)
954 call col2(this%flux3, this%n3, this%n_large)
955 call add3(this%G, this%flux1, this%flux2, this%n_large)
956 call add2(this%G, this%flux3, this%n_large)
957 end if
958
959 call this%gs_GJP%op(this%G, this%n_large, gs_op_add)
960
961 end subroutine g_compute
962
967 subroutine absvolflux_compute(this, u, v, w)
968 class(gradient_jump_penalty_t), intent(inout) :: this
969 type(field_t), intent(in) :: u, v, w
970
971 integer :: i
972
973 if (neko_bcknd_device .eq. 1) then
974 call device_pick_facet_value_hex(this%volflux1_d, u%x_d, this%lx, &
975 this%coef%msh%nelv)
976 call device_pick_facet_value_hex(this%volflux2_d, v%x_d, this%lx, &
977 this%coef%msh%nelv)
978 call device_pick_facet_value_hex(this%volflux3_d, w%x_d, this%lx, &
979 this%coef%msh%nelv)
980 call device_col2(this%volflux1_d, this%n1_d, this%n_large)
981 call device_col2(this%volflux2_d, this%n2_d, this%n_large)
982 call device_col2(this%volflux3_d, this%n3_d, this%n_large)
983 call device_add3s2(this%absvolflux_d, this%volflux1_d, &
984 this%volflux2_d, 1.0_rp, 1.0_rp, this%n_large)
985 call device_add2(this%absvolflux_d, this%volflux3_d, this%n_large)
986 call device_absval(this%absvolflux_d, this%n_large)
987 else
988 call pick_facet_value_hex(this%volflux1, u%x, &
989 this%lx, this%coef%msh%nelv)
990 call pick_facet_value_hex(this%volflux2, v%x, &
991 this%lx, this%coef%msh%nelv)
992 call pick_facet_value_hex(this%volflux3, w%x, &
993 this%lx, this%coef%msh%nelv)
994 call col2(this%volflux1, this%n1, this%n_large)
995 call col2(this%volflux2, this%n2, this%n_large)
996 call col2(this%volflux3, this%n3, this%n_large)
997 call add3(this%absvolflux, this%volflux1, this%volflux2, this%n_large)
998 call add2(this%absvolflux, this%volflux3, this%n_large)
999 call absval(this%absvolflux, this%n_large)
1000 end if
1001
1002 end subroutine absvolflux_compute
1003
1009 subroutine pick_facet_value_hex(f_facet, f_field, lx, nelv)
1010 integer, intent(in) :: lx, nelv
1011 real(kind=rp), intent(in) :: f_field(lx, lx, lx, nelv)
1012 real(kind=rp), intent(inout) :: f_facet(lx + 2, lx + 2, lx + 2, nelv)
1013
1014 call copy(f_facet(1, 2: lx + 1, 2: lx + 1, :), &
1015 f_field(1, :, :, :), lx * lx * nelv)
1016 call copy(f_facet(lx + 2, 2: lx + 1, 2: lx + 1, :), &
1017 f_field(lx, :, :, :), lx * lx * nelv)
1018 call copy(f_facet(2: lx + 1, 1, 2: lx + 1, :), &
1019 f_field(:, 1, :, :), lx * lx * nelv)
1020 call copy(f_facet(2: lx + 1, lx + 2, 2: lx + 1, :), &
1021 f_field(:, lx, :, :), lx * lx * nelv)
1022 call copy(f_facet(2: lx + 1, 2: lx + 1, 1, :), &
1023 f_field(:, :, 1, :), lx * lx * nelv)
1024 call copy(f_facet(2: lx + 1, 2: lx + 1, lx + 2, :), &
1025 f_field(:, :, lx, :), lx * lx * nelv)
1026
1027 end subroutine pick_facet_value_hex
1028
1029end module gradient_jump_penalty
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
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...
Compute derivative of a scalar field along a single direction.
Definition operators.f90:79
Coefficients.
Definition coef.f90:34
subroutine, public device_gradient_jump_penalty_finalize(penalty_d, penalty_facet_d, dphidxi_d, nx, nelv)
subroutine, public device_pick_facet_value_hex(b_d, a_d, nx, nelv)
subroutine, public device_add2s2(a_d, b_d, c1, n, strm)
Vector addition with scalar multiplication (multiplication on first argument)
subroutine, public device_add2(a_d, b_d, n, strm)
Vector addition .
subroutine, public device_add3s2(a_d, b_d, c_d, c1, c2, n, strm)
Returns .
subroutine, public device_col2(a_d, b_d, n, strm)
Vector multiplication .
subroutine, public device_absval(a_d, n, strm)
subroutine, public device_invcol2(a_d, b_d, n, strm)
Vector division .
subroutine, public device_col3(a_d, b_d, c_d, n, strm)
Vector multiplication with 3 vectors .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:48
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Defines a field.
Definition field.f90:34
Gather-scatter.
Implements gradient_jump_penalty_t.
subroutine gradient_jump_penalty_finalize_hex(penalty, wa, dphidxi, lx, nelv)
Finalizinge the gradient jump penalty term for hexahedral elements. <tau * h^2 * absvolflux * G * phi...
subroutine gradient_jump_penalty_finalize(penalty, wa, dphidxi, lx, nelv)
Interface of finalizing the gradient jump penalty term. <tau * h^2 * absvolflux * G * phij * phik * d...
subroutine gradient_jump_penalty_compute_single(this, s)
Compute the gradient jump penalty term for a single field.
subroutine absvolflux_compute(this, u, v, w)
Compute the average of the volumetric flux over facets.
subroutine facet_factor_init(this)
Initialize the facet factor array.
subroutine g_compute(this, s)
Compute the average of the flux over facets.
real(kind=rp) function dist2_quadrature_hex(l, k, j, i, n, dm, coef)
subroutine pick_facet_value_hex(f_facet, f_field, lx, nelv)
Pick facet values of a field.
subroutine gradient_jump_penalty_init(this, json, fields, coef, variable_name)
Constructor.
subroutine eval_h2_hex(h2_el, n, i, coef)
Evaluate h^2 for each element for hexahedral mesh.
subroutine gradient_jump_penalty_compute(this, time)
Assign the gradient jump penalty term.
subroutine gradient_jump_penalty_init_from_components(this, coef, fields, start_time, end_time, a, b, variable_name)
Constructor from components.
subroutine gradient_jump_penalty_free(this)
Destructor for the gradient_jump_penalty_t class.
Defines Gather-scatter operations.
Definition gs_ops.f90:34
integer, parameter, public gs_op_add
Definition gs_ops.f90:36
Defines a hexahedron element.
Definition hex.f90:34
Utilities for retrieving parameters from the case files.
Definition math.f90:60
subroutine, public invcol2(a, b, n)
Vector division .
Definition math.f90:1033
subroutine, public add3(a, b, c, n)
Vector addition .
Definition math.f90:918
subroutine, public add2(a, b, n)
Vector addition .
Definition math.f90:903
subroutine, public absval(a, n)
Take the absolute value of an array.
Definition math.f90:1643
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:1049
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:294
subroutine, public col3(a, b, c, n)
Vector multiplication with 3 vectors .
Definition math.f90:1064
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Operators.
Definition operators.f90:34
Implements a point.
Definition point.f90:35
Defines a quadrilateral element.
Definition quad.f90:34
Defines a registry for storing solution fields.
Definition registry.f90:34
type(registry_t), target, public neko_registry
Global field registry.
Definition registry.f90:144
Implements the source_term_t type and a wrapper source_term_wrapper_t.
Defines a function space.
Definition space.f90:34
integer, parameter, public gll
Definition space.f90:50
Module with things related to the simulation time.
Utilities.
Definition utils.f90:35
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:93
Base type for an element.
Definition element.f90:44
field_list_t, To be able to group fields together
Gather-scatter kernel.
Hexahedron element.
Definition hex.f90:63
A point in with coordinates .
Definition point.f90:43
Quadrilateral element.
Definition quad.f90:58
Base abstract type for source terms.
The function space for the SEM solution fields.
Definition space.f90:64
A struct that contains all info about the time, expand as needed.