@@ -12,6 +12,16 @@ module m_bubbles_EL_kernels
1212
1313 implicit none
1414
15+ ! Cell- centered pressure gradients (precomputed for translational motion)
16+ real (wp), allocatable, dimension (:, :, :) :: grad_p_x, grad_p_y, grad_p_z
17+ $:GPU_DECLARE(create= ' [grad_p_x, grad_p_y, grad_p_z]' )
18+
19+ ! Finite- difference coefficients for pressure gradient computation
20+ real (wp), allocatable, dimension (:, :) :: fd_coeff_x_pgrad
21+ real (wp), allocatable, dimension (:, :) :: fd_coeff_y_pgrad
22+ real (wp), allocatable, dimension (:, :) :: fd_coeff_z_pgrad
23+ $:GPU_DECLARE(create= ' [fd_coeff_x_pgrad, fd_coeff_y_pgrad, fd_coeff_z_pgrad]' )
24+
1525contains
1626
1727 !> The purpose of this subroutine is to smear the strength of the lagrangian
@@ -372,6 +382,71 @@ contains
372382
373383 end subroutine s_get_cell
374384
385+ !> Precomputes cell- centered pressure gradients (dp/ dx, dp/ dy, dp/ dz) at all cell centers
386+ !! using finite- difference coefficients of the specified order. This avoids
387+ !! scattered memory accesses to the pressure field when computing translational
388+ !! bubble forces.
389+ !! @param q_prim_vf Primitive variables (pressure is at index E_idx)
390+ subroutine s_compute_pressure_gradients (q_prim_vf )
391+
392+ type(scalar_field), dimension (sys_size), intent (in ) :: q_prim_vf
393+
394+ integer :: i, j, k, r
395+
396+ ! dp/ dx at all cell centers
397+ $:GPU_PARALLEL_LOOP(private= ' [i,j,k,r]' , collapse= 3 )
398+ do k = 0 , p
399+ do j = 0 , n
400+ do i = 0 , m
401+ grad_p_x(i, j, k) = 0._wp
402+ $:GPU_LOOP(parallelism= ' [seq]' )
403+ do r = - fd_number, fd_number
404+ grad_p_x(i, j, k) = grad_p_x(i, j, k) + &
405+ q_prim_vf(E_idx)%sf(i + r, j, k)* fd_coeff_x_pgrad(r, i)
406+ end do
407+ end do
408+ end do
409+ end do
410+ $:END_GPU_PARALLEL_LOOP()
411+
412+ ! dp/ dy at all cell centers
413+ if (n > 0 ) then
414+ $:GPU_PARALLEL_LOOP(private= ' [i,j,k,r]' , collapse= 3 )
415+ do k = 0 , p
416+ do j = 0 , n
417+ do i = 0 , m
418+ grad_p_y(i, j, k) = 0._wp
419+ $:GPU_LOOP(parallelism= ' [seq]' )
420+ do r = - fd_number, fd_number
421+ grad_p_y(i, j, k) = grad_p_y(i, j, k) + &
422+ q_prim_vf(E_idx)%sf(i, j + r, k)* fd_coeff_y_pgrad(r, j)
423+ end do
424+ end do
425+ end do
426+ end do
427+ $:END_GPU_PARALLEL_LOOP()
428+ end if
429+
430+ ! dp/ dz at all cell centers
431+ if (p > 0 ) then
432+ $:GPU_PARALLEL_LOOP(private= ' [i,j,k,r]' , collapse= 3 )
433+ do k = 0 , p
434+ do j = 0 , n
435+ do i = 0 , m
436+ grad_p_z(i, j, k) = 0._wp
437+ $:GPU_LOOP(parallelism= ' [seq]' )
438+ do r = - fd_number, fd_number
439+ grad_p_z(i, j, k) = grad_p_z(i, j, k) + &
440+ q_prim_vf(E_idx)%sf(i, j, k + r)* fd_coeff_z_pgrad(r, k)
441+ end do
442+ end do
443+ end do
444+ end do
445+ $:END_GPU_PARALLEL_LOOP()
446+ end if
447+
448+ end subroutine s_compute_pressure_gradients
449+
375450 !! This function interpolates the velocity of Eulerian field at the position
376451 !! of the bubble.
377452 !! @param pos Position of the bubble in directiion i
@@ -491,74 +566,8 @@ contains
491566 integer , intent (in ) :: i
492567 type(scalar_field), dimension (sys_size), intent (in ) :: q_prim_vf
493568
494- real (wp) :: a, dp, vol, force
569+ real (wp) :: dp, vol, force
495570 real (wp) :: v_rel
496- real (wp), dimension (fd_order) :: xi, eta, L
497-
498- if (fd_order <= 2 ) then
499- if (i == 1 ) then
500- dp = (q_prim_vf(E_idx)%sf(cell(1 ) + 1 , cell(2 ), cell(3 )) - &
501- q_prim_vf(E_idx)%sf(cell(1 ) - 1 , cell(2 ), cell(3 )))/ &
502- (x_cc(cell(1 ) + 1 ) - x_cc(cell(1 ) - 1 ))
503- elseif (i == 2 ) then
504- dp = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ) + 1 , cell(3 )) - &
505- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ) - 1 , cell(3 )))/ &
506- (y_cc(cell(2 ) + 1 ) - y_cc(cell(2 ) - 1 ))
507- elseif (i == 3 ) then
508- dp = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 ) + 1 ) - &
509- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 ) - 1 ))/ &
510- (z_cc(cell(3 ) + 1 ) - z_cc(cell(3 ) - 1 ))
511- end if
512- elseif (fd_order == 4 ) then
513- if (i == 1 ) then
514- xi(1 ) = x_cc(cell(1 ) - 1 )
515- eta(1 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 )) - &
516- q_prim_vf(E_idx)%sf(cell(1 ) - 2 , cell(2 ), cell(3 )))/ &
517- (x_cc(cell(1 )) - x_cc(cell(1 ) - 2 ))
518- xi(2 ) = x_cc(cell(1 ))
519- eta(2 ) = (q_prim_vf(E_idx)%sf(cell(1 ) + 1 , cell(2 ), cell(3 )) - &
520- q_prim_vf(E_idx)%sf(cell(1 ) - 1 , cell(2 ), cell(3 )))/ &
521- (x_cc(cell(1 ) + 1 ) - x_cc(cell(1 ) - 1 ))
522- xi(3 ) = x_cc(cell(1 ) + 1 )
523- eta(3 ) = (q_prim_vf(E_idx)%sf(cell(1 ) + 2 , cell(2 ), cell(3 )) - &
524- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 )))/ &
525- (x_cc(cell(1 ) + 2 ) - x_cc(cell(1 )))
526- elseif (i == 2 ) then
527- xi(1 ) = y_cc(cell(2 ) - 1 )
528- eta(1 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 )) - &
529- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ) - 2 , cell(3 )))/ &
530- (y_cc(cell(2 )) - y_cc(cell(2 ) - 2 ))
531- xi(2 ) = y_cc(cell(2 ))
532- eta(2 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ) + 1 , cell(3 )) - &
533- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ) - 1 , cell(3 )))/ &
534- (y_cc(cell(2 ) + 1 ) - y_cc(cell(2 ) - 1 ))
535- xi(3 ) = y_cc(cell(2 ) + 1 )
536- eta(3 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ) + 2 , cell(3 )) - &
537- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 )))/ &
538- (y_cc(cell(2 ) + 2 ) - y_cc(cell(2 )))
539- elseif (i == 3 ) then
540- xi(1 ) = z_cc(cell(3 ) - 1 )
541- eta(1 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 )) - &
542- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 ) - 2 ))/ &
543- (z_cc(cell(3 )) - z_cc(cell(3 ) - 2 ))
544- xi(2 ) = z_cc(cell(3 ))
545- eta(2 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 ) + 1 ) - &
546- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 ) - 1 ))/ &
547- (z_cc(cell(3 ) + 1 ) - z_cc(cell(3 ) - 1 ))
548- xi(3 ) = z_cc(cell(3 ) + 1 )
549- eta(3 ) = (q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 ) + 2 ) - &
550- q_prim_vf(E_idx)%sf(cell(1 ), cell(2 ), cell(3 )))/ &
551- (z_cc(cell(3 ) + 2 ) - z_cc(cell(3 )))
552- end if
553-
554- L(1 ) = ((pos - xi(2 ))* (pos - xi(3 )))/ ((xi(1 ) - xi(2 ))* (xi(1 ) - xi(3 )))
555- L(2 ) = ((pos - xi(1 ))* (pos - xi(3 )))/ ((xi(2 ) - xi(1 ))* (xi(2 ) - xi(3 )))
556- L(3 ) = ((pos - xi(1 ))* (pos - xi(2 )))/ ((xi(3 ) - xi(1 ))* (xi(3 ) - xi(2 )))
557-
558- dp = L(1 )* eta(1 ) + L(2 )* eta(2 ) + L(3 )* eta(3 )
559- end if
560-
561- vol = (4._wp / 3._wp )* pi* (rad** 3._wp )
562571
563572 if (fd_order > 1 ) then
564573 v_rel = vel - f_interpolate_velocity(pos, cell, i, q_prim_vf)
@@ -576,7 +585,17 @@ contains
576585 force = force - (12._wp * pi* rad* v_rel)/ Re
577586 end if
578587
579- if (lag_params%pressure_force) then
588+ if (lag_pressure_force) then
589+ ! Use precomputed cell- centered pressure gradients
590+ if (i == 1 ) then
591+ dp = grad_p_x(cell(1 ), cell(2 ), cell(3 ))
592+ elseif (i == 2 ) then
593+ dp = grad_p_y(cell(1 ), cell(2 ), cell(3 ))
594+ elseif (i == 3 ) then
595+ dp = grad_p_z(cell(1 ), cell(2 ), cell(3 ))
596+ end if
597+
598+ vol = (4._wp / 3._wp )* pi* (rad** 3._wp )
580599 force = force - vol* dp
581600 end if
582601
0 commit comments