Skip to content

Commit df51a3c

Browse files
authored
move pressure relaxation to its own module + refac (#865)
1 parent 443c33c commit df51a3c

File tree

4 files changed

+351
-270
lines changed

4 files changed

+351
-270
lines changed

misc/length-subroutines.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/bash
2+
3+
# Use gawk if available, otherwise fall back to awk
4+
if command -v gawk > /dev/null; then
5+
AWK_CMD="gawk"
6+
IGNORECASE_BLOCK='BEGIN { IGNORECASE = 1 }'
7+
else
8+
AWK_CMD="awk"
9+
IGNORECASE_BLOCK=''
10+
echo "Warning: gawk not found. Case-insensitive matching may not work as expected." >&2
11+
fi
12+
13+
find . -type f \( -name "*.f90" -o -name "*.fpp" \) | while read file; do
14+
"$AWK_CMD" "
15+
$IGNORECASE_BLOCK
16+
/^[ \t]*((pure|elemental|impure)[ \t]+)*subroutine[ \t]+[a-zA-Z_][a-zA-Z0-9_]*[ \t]*\\(/ {
17+
in_sub = 1
18+
match(\$0, /subroutine[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)/, arr)
19+
sub_name = arr[1]
20+
start_line = NR
21+
next
22+
}
23+
/^[ \t]*end[ \t]+subroutine[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)?[ \t]*\$/ && in_sub {
24+
end_line = NR
25+
print (end_line - start_line + 1) \"\t\" FILENAME \": \" sub_name
26+
in_sub = 0
27+
}
28+
" "$file"
29+
done | sort -nr | awk -F'\t' '{print $2 " : " $1 " lines"}' | head -20
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
!>
2+
!! @file m_pressure_relaxation.fpp
3+
!! @brief Contains module m_pressure_relaxation
4+
5+
#:include 'case.fpp'
6+
#:include 'macros.fpp'
7+
8+
!> @brief The module contains the subroutines used to perform pressure relaxation
9+
!! for multi-component flows using the 6-equation model. This includes
10+
!! volume fraction correction, Newton-Raphson pressure equilibration, and
11+
!! internal energy correction to maintain thermodynamic consistency.
12+
module m_pressure_relaxation
13+
14+
use m_derived_types !< Definitions of the derived types
15+
use m_global_parameters !< Definitions of the global parameters
16+
17+
implicit none
18+
19+
private; public :: s_pressure_relaxation_procedure, &
20+
s_initialize_pressure_relaxation_module, &
21+
s_finalize_pressure_relaxation_module
22+
23+
real(wp), allocatable, dimension(:) :: gamma_min, pres_inf
24+
!$acc declare create(gamma_min, pres_inf)
25+
26+
real(wp), allocatable, dimension(:, :) :: Res
27+
!$acc declare create(Res)
28+
29+
contains
30+
31+
!> Initialize the pressure relaxation module
32+
impure subroutine s_initialize_pressure_relaxation_module
33+
34+
integer :: i, j
35+
36+
@:ALLOCATE(gamma_min(1:num_fluids), pres_inf(1:num_fluids))
37+
38+
do i = 1, num_fluids
39+
gamma_min(i) = 1._wp/fluid_pp(i)%gamma + 1._wp
40+
pres_inf(i) = fluid_pp(i)%pi_inf/(1._wp + fluid_pp(i)%gamma)
41+
end do
42+
!$acc update device(gamma_min, pres_inf)
43+
44+
if (viscous) then
45+
@:ALLOCATE(Res(1:2, 1:maxval(Re_size)))
46+
do i = 1, 2
47+
do j = 1, Re_size(i)
48+
Res(i, j) = fluid_pp(Re_idx(i, j))%Re(i)
49+
end do
50+
end do
51+
!$acc update device(Res, Re_idx, Re_size)
52+
end if
53+
54+
end subroutine s_initialize_pressure_relaxation_module
55+
56+
!> Finalize the pressure relaxation module
57+
impure subroutine s_finalize_pressure_relaxation_module
58+
59+
@:DEALLOCATE(gamma_min, pres_inf)
60+
if (viscous) then
61+
@:DEALLOCATE(Res)
62+
end if
63+
64+
end subroutine s_finalize_pressure_relaxation_module
65+
66+
!> The main pressure relaxation procedure
67+
!! @param q_cons_vf Cell-average conservative variables
68+
pure subroutine s_pressure_relaxation_procedure(q_cons_vf)
69+
70+
type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
71+
integer :: j, k, l
72+
73+
!$acc parallel loop collapse(3) gang vector default(present)
74+
do l = 0, p
75+
do k = 0, n
76+
do j = 0, m
77+
call s_relax_cell_pressure(q_cons_vf, j, k, l)
78+
end do
79+
end do
80+
end do
81+
82+
end subroutine s_pressure_relaxation_procedure
83+
84+
!> Process pressure relaxation for a single cell
85+
pure subroutine s_relax_cell_pressure(q_cons_vf, j, k, l)
86+
!$acc routine seq
87+
88+
type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
89+
integer, intent(in) :: j, k, l
90+
91+
! Volume fraction correction
92+
if (mpp_lim) call s_correct_volume_fractions(q_cons_vf, j, k, l)
93+
94+
! Pressure equilibration
95+
if (s_needs_pressure_relaxation(q_cons_vf, j, k, l)) then
96+
call s_equilibrate_pressure(q_cons_vf, j, k, l)
97+
end if
98+
99+
! Internal energy correction
100+
call s_correct_internal_energies(q_cons_vf, j, k, l)
101+
102+
end subroutine s_relax_cell_pressure
103+
104+
!> Check if pressure relaxation is needed for this cell
105+
pure logical function s_needs_pressure_relaxation(q_cons_vf, j, k, l)
106+
!$acc routine seq
107+
108+
type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf
109+
integer, intent(in) :: j, k, l
110+
integer :: i
111+
112+
s_needs_pressure_relaxation = .true.
113+
!$acc loop seq
114+
do i = 1, num_fluids
115+
if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > (1._wp - sgm_eps)) then
116+
s_needs_pressure_relaxation = .false.
117+
end if
118+
end do
119+
120+
end function s_needs_pressure_relaxation
121+
122+
!> Correct volume fractions to physical bounds
123+
pure subroutine s_correct_volume_fractions(q_cons_vf, j, k, l)
124+
!$acc routine seq
125+
126+
type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
127+
integer, intent(in) :: j, k, l
128+
real(wp) :: sum_alpha
129+
integer :: i
130+
131+
sum_alpha = 0._wp
132+
!$acc loop seq
133+
do i = 1, num_fluids
134+
if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. &
135+
(q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then
136+
q_cons_vf(i + contxb - 1)%sf(j, k, l) = 0._wp
137+
q_cons_vf(i + advxb - 1)%sf(j, k, l) = 0._wp
138+
q_cons_vf(i + intxb - 1)%sf(j, k, l) = 0._wp
139+
end if
140+
if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) &
141+
q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp
142+
sum_alpha = sum_alpha + q_cons_vf(i + advxb - 1)%sf(j, k, l)
143+
end do
144+
145+
!$acc loop seq
146+
do i = 1, num_fluids
147+
q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)/sum_alpha
148+
end do
149+
150+
end subroutine s_correct_volume_fractions
151+
152+
!> Main pressure equilibration using Newton-Raphson
153+
pure subroutine s_equilibrate_pressure(q_cons_vf, j, k, l)
154+
!$acc routine seq
155+
156+
type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
157+
integer, intent(in) :: j, k, l
158+
159+
real(wp) :: pres_relax, f_pres, df_pres
160+
real(wp), dimension(num_fluids) :: pres_K_init, rho_K_s
161+
integer, parameter :: MAX_ITER = 50
162+
real(wp), parameter :: TOLERANCE = 1e-10_wp
163+
integer :: iter, i
164+
165+
! Initialize pressures
166+
pres_relax = 0._wp
167+
!$acc loop seq
168+
do i = 1, num_fluids
169+
if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then
170+
pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/ &
171+
q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i)
172+
if (pres_K_init(i) <= -(1._wp - 1e-8_wp)*pres_inf(i) + 1e-8_wp) &
173+
pres_K_init(i) = -(1._wp - 1e-8_wp)*pres_inf(i) + 1e-8_wp
174+
else
175+
pres_K_init(i) = 0._wp
176+
end if
177+
pres_relax = pres_relax + q_cons_vf(i + advxb - 1)%sf(j, k, l)*pres_K_init(i)
178+
end do
179+
180+
! Newton-Raphson iteration
181+
f_pres = 1e-9_wp
182+
df_pres = 1e9_wp
183+
!$acc loop seq
184+
do iter = 0, MAX_ITER - 1
185+
if (abs(f_pres) > TOLERANCE) then
186+
pres_relax = pres_relax - f_pres/df_pres
187+
188+
! Enforce pressure bounds
189+
do i = 1, num_fluids
190+
if (pres_relax <= -(1._wp - 1e-8_wp)*pres_inf(i) + 1e-8_wp) &
191+
pres_relax = -(1._wp - 1e-8_wp)*pres_inf(i) + 1._wp
192+
end do
193+
194+
! Newton-Raphson step
195+
f_pres = -1._wp
196+
df_pres = 0._wp
197+
!$acc loop seq
198+
do i = 1, num_fluids
199+
if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then
200+
rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/ &
201+
max(q_cons_vf(i + advxb - 1)%sf(j, k, l), sgm_eps) &
202+
*((pres_relax + pres_inf(i))/(pres_K_init(i) + &
203+
pres_inf(i)))**(1._wp/gamma_min(i))
204+
f_pres = f_pres + q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i)
205+
df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l) &
206+
/(gamma_min(i)*rho_K_s(i)*(pres_relax + pres_inf(i)))
207+
end if
208+
end do
209+
end if
210+
end do
211+
212+
! Update volume fractions
213+
!$acc loop seq
214+
do i = 1, num_fluids
215+
if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) &
216+
q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i)
217+
end do
218+
219+
end subroutine s_equilibrate_pressure
220+
221+
!> Correct internal energies using equilibrated pressure
222+
pure subroutine s_correct_internal_energies(q_cons_vf, j, k, l)
223+
!$acc routine seq
224+
225+
type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
226+
integer, intent(in) :: j, k, l
227+
228+
real(wp), dimension(num_fluids) :: alpha_rho, alpha
229+
real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha
230+
real(wp), dimension(2) :: Re
231+
integer :: i, q
232+
233+
!$acc loop seq
234+
do i = 1, num_fluids
235+
alpha_rho(i) = q_cons_vf(i)%sf(j, k, l)
236+
alpha(i) = q_cons_vf(E_idx + i)%sf(j, k, l)
237+
end do
238+
239+
! Compute mixture properties (combined bubble and standard logic)
240+
rho = 0._wp
241+
gamma = 0._wp
242+
pi_inf = 0._wp
243+
244+
if (bubbles_euler) then
245+
if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then
246+
!$acc loop seq
247+
do i = 1, num_fluids
248+
rho = rho + alpha_rho(i)
249+
gamma = gamma + alpha(i)*gammas(i)
250+
pi_inf = pi_inf + alpha(i)*pi_infs(i)
251+
end do
252+
else if ((model_eqns == 2) .and. (num_fluids > 2)) then
253+
!$acc loop seq
254+
do i = 1, num_fluids - 1
255+
rho = rho + alpha_rho(i)
256+
gamma = gamma + alpha(i)*gammas(i)
257+
pi_inf = pi_inf + alpha(i)*pi_infs(i)
258+
end do
259+
else
260+
rho = alpha_rho(1)
261+
gamma = gammas(1)
262+
pi_inf = pi_infs(1)
263+
end if
264+
else
265+
sum_alpha = 0._wp
266+
if (mpp_lim) then
267+
!$acc loop seq
268+
do i = 1, num_fluids
269+
alpha_rho(i) = max(0._wp, alpha_rho(i))
270+
alpha(i) = min(max(0._wp, alpha(i)), 1._wp)
271+
sum_alpha = sum_alpha + alpha(i)
272+
end do
273+
alpha = alpha/max(sum_alpha, sgm_eps)
274+
end if
275+
276+
!$acc loop seq
277+
do i = 1, num_fluids
278+
rho = rho + alpha_rho(i)
279+
gamma = gamma + alpha(i)*gammas(i)
280+
pi_inf = pi_inf + alpha(i)*pi_infs(i)
281+
end do
282+
283+
if (viscous) then
284+
!$acc loop seq
285+
do i = 1, 2
286+
Re(i) = dflt_real
287+
if (Re_size(i) > 0) Re(i) = 0._wp
288+
!$acc loop seq
289+
do q = 1, Re_size(i)
290+
Re(i) = alpha(Re_idx(i, q))/Res(i, q) + Re(i)
291+
end do
292+
Re(i) = 1._wp/max(Re(i), sgm_eps)
293+
end do
294+
end if
295+
end if
296+
297+
! Compute dynamic pressure and update internal energies
298+
dyn_pres = 0._wp
299+
!$acc loop seq
300+
do i = momxb, momxe
301+
dyn_pres = dyn_pres + 5e-1_wp*q_cons_vf(i)%sf(j, k, l)* &
302+
q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps)
303+
end do
304+
305+
pres_relax = (q_cons_vf(E_idx)%sf(j, k, l) - dyn_pres - pi_inf)/gamma
306+
307+
!$acc loop seq
308+
do i = 1, num_fluids
309+
q_cons_vf(i + intxb - 1)%sf(j, k, l) = &
310+
q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i))
311+
end do
312+
313+
end subroutine s_correct_internal_energies
314+
315+
end module m_pressure_relaxation

0 commit comments

Comments
 (0)