Skip to content

Commit ae27d22

Browse files
Merge pull request #15 from tumaer/Riemann-viscous-BC-fix
Riemann viscous BC fix
2 parents 669d8b3 + fa16435 commit ae27d22

File tree

3 files changed

+50
-20
lines changed

3 files changed

+50
-20
lines changed

jax_sph/solver.py

+47-17
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def rho_evol_riemann_fn(
4747
wall_mask_j,
4848
n_w_j,
4949
g_ext_i,
50+
u_tilde_j,
5051
**kwargs,
5152
):
5253
# Compute unit vector, above eq. (6), Zhang (2017)
@@ -56,18 +57,22 @@ def rho_evol_riemann_fn(
5657
kernel_grad = kernel_fn.grad_w(d_ij) * (e_ij)
5758

5859
# Compute average states eq. (6)/(12)/(13), Zhang (2017)
59-
u_L = jnp.where(wall_mask_j == 1, jnp.dot(u_i, -n_w_j), jnp.dot(u_i, -e_ij))
60+
u_L = jnp.where(
61+
jnp.isin(wall_mask_j, wall_tags), jnp.dot(u_i, -n_w_j), jnp.dot(u_i, -e_ij)
62+
)
6063
p_L = p_i
6164
rho_L = rho_i
6265

6366
# u_w from eq. (15), Yang (2020)
6467
u_R = jnp.where(
65-
wall_mask_j == 1,
68+
jnp.isin(wall_mask_j, wall_tags),
6669
-u_L + 2 * jnp.dot(u_j, n_w_j),
6770
jnp.dot(u_j, -e_ij),
6871
)
69-
p_R = jnp.where(wall_mask_j == 1, p_L + rho_L * jnp.dot(g_ext_i, -r_ij), p_j)
70-
rho_R = jnp.where(wall_mask_j == 1, eos.rho_fn(p_R), rho_j)
72+
p_R = jnp.where(
73+
jnp.isin(wall_mask_j, wall_tags), p_L + rho_L * jnp.dot(g_ext_i, -r_ij), p_j
74+
)
75+
rho_R = jnp.where(jnp.isin(wall_mask_j, wall_tags), eos.rho_fn(p_R), rho_j)
7176

7277
U_avg = (u_L + u_R) / 2
7378
v_avg = (u_i + u_j) / 2
@@ -197,6 +202,7 @@ def acceleration_fn_riemann(
197202
mask,
198203
n_w_j,
199204
g_ext_i,
205+
u_tilde_j,
200206
):
201207
# Compute unit vector, above eq. (6), Zhang (2017)
202208
e_ij = e_s
@@ -206,18 +212,22 @@ def acceleration_fn_riemann(
206212
kernel_grad = kernel_part_diff * (e_ij)
207213

208214
# Compute average states eq. (6)/(12)/(13), Zhang (2017)
209-
u_L = jnp.where(wall_mask_j == 1, jnp.dot(u_i, -n_w_j), jnp.dot(u_i, -e_ij))
215+
u_L = jnp.where(
216+
jnp.isin(wall_mask_j, wall_tags), jnp.dot(u_i, -n_w_j), jnp.dot(u_i, -e_ij)
217+
)
210218
p_L = p_i
211219
rho_L = rho_i
212220

213-
# u_w from eq. (15), Yang (2020)
221+
# u_w from eq. (15), Yang (2020)
214222
u_R = jnp.where(
215-
wall_mask_j == 1,
223+
jnp.isin(wall_mask_j, wall_tags),
216224
-u_L + 2 * jnp.dot(u_j, n_w_j),
217225
jnp.dot(u_j, -e_ij),
218226
)
219-
p_R = jnp.where(wall_mask_j == 1, p_L + rho_L * jnp.dot(g_ext_i, -r_ij), p_j)
220-
rho_R = jnp.where(wall_mask_j == 1, eos.rho_fn(p_R), rho_j)
227+
p_R = jnp.where(
228+
jnp.isin(wall_mask_j, wall_tags), p_L + rho_L * jnp.dot(g_ext_i, -r_ij), p_j
229+
)
230+
rho_R = jnp.where(jnp.isin(wall_mask_j, wall_tags), eos.rho_fn(p_R), rho_j)
221231

222232
P_avg = (p_L + p_R) / 2
223233
rho_avg = (rho_L + rho_R) / 2
@@ -227,16 +237,18 @@ def acceleration_fn_riemann(
227237
eta_ij = 2 * eta_i * eta_j / (eta_i + eta_j + EPS)
228238

229239
# Compute Riemann states eq. (7) and (10), Zhang (2017)
230-
# u_R = jnp.where(
231-
# wall_mask_j == 1, -u_L - 2 * jnp.dot(v_j, -n_w_j), jnp.dot(v_j, -e_ij)
232-
# )
233240
P_star = P_avg + 0.5 * rho_avg * (u_L - u_R) * beta_fn(u_L, u_R, eta_limiter)
234241

235242
# pressure term with linear Riemann solver eq. (9), Zhang (2017)
236243
eq_9 = -2 * m_j * (P_star / (rho_i * rho_j)) * kernel_grad
237244

238245
# viscosity term eq. (6), Zhang (2019)
239-
v_ij = u_i - u_j
246+
u_d = 2 * u_j - u_tilde_j
247+
v_ij = jnp.where(
248+
jnp.isin(wall_mask_j, wall_tags),
249+
u_i - u_d,
250+
u_i - u_j,
251+
)
240252
eq_6 = 2 * m_j * eta_ij / (rho_i * rho_j) * v_ij / (d_ij + EPS)
241253
eq_6 *= kernel_part_diff * mask
242254

@@ -388,11 +400,21 @@ def gwbc_fn_riemann_wrapper(is_free_slip, is_heat_conduction):
388400

389401
def free_weight(fluid_mask_i, tag_i):
390402
return fluid_mask_i
403+
404+
def riemann_velocities(u, w_dist, fluid_mask, i_s, j_s, N):
405+
return u
391406
else:
392407

393408
def free_weight(fluid_mask_i, tag_i):
394409
return jnp.ones_like(tag_i)
395410

411+
def riemann_velocities(u, w_dist, fluid_mask, i_s, j_s, N):
412+
w_dist_fluid = w_dist * fluid_mask[j_s]
413+
u_wall_nom = ops.segment_sum(w_dist_fluid[:, None] * u[j_s], i_s, N)
414+
u_wall_denom = ops.segment_sum(w_dist_fluid, i_s, N)
415+
u_tilde = u_wall_nom / (u_wall_denom[:, None] + EPS)
416+
return u_tilde
417+
396418
if is_heat_conduction:
397419

398420
def heat_bc(mask_j_s_fluid, w_dist, temperature, i_s, j_s, tag, N):
@@ -410,7 +432,7 @@ def heat_bc(mask_j_s_fluid, w_dist, temperature, i_s, j_s, tag, N):
410432
def heat_bc(mask_j_s_fluid, w_dist, temperature, i_s, j_s, tag, N):
411433
return temperature
412434

413-
return free_weight, heat_bc
435+
return free_weight, riemann_velocities, heat_bc
414436

415437

416438
def limiter_fn_wrapper(eta_limiter, c_ref):
@@ -503,9 +525,11 @@ def __init__(
503525
self._kernel_fn = SuperGaussianKernel(h=dx, dim=dim)
504526

505527
self._gwbc_fn = gwbc_fn_wrapper(is_free_slip, is_heat_conduction, eos)
506-
self._free_weight, self._heat_bc = gwbc_fn_riemann_wrapper(
507-
is_free_slip, is_heat_conduction
508-
)
528+
(
529+
self._free_weight,
530+
self._riemann_velocities,
531+
self._heat_bc,
532+
) = gwbc_fn_riemann_wrapper(is_free_slip, is_heat_conduction)
509533
self._acceleration_tvf_fn = acceleration_tvf_fn_wrapper(self._kernel_fn)
510534
self._acceleration_riemann_fn = acceleration_riemann_fn_wrapper(
511535
self._kernel_fn, eos, _beta_fn, eta_limiter
@@ -572,6 +596,10 @@ def forward(state, neighbors):
572596
)
573597
n_w = jnp.where(jnp.absolute(n_w) < EPS, 0.0, n_w)
574598

599+
##### Riemann velocity BCs
600+
if self.is_bc_trick and (self.solver == "RIE"):
601+
u_tilde = self._riemann_velocities(u, w_dist, fluid_mask, i_s, j_s, N)
602+
575603
##### Density summation or evolution
576604

577605
# update evolution
@@ -598,6 +626,7 @@ def forward(state, neighbors):
598626
wall_mask[j_s],
599627
n_w[j_s],
600628
g_ext[i_s],
629+
u_tilde[j_s],
601630
)
602631
drhodt = ops.segment_sum(temp, i_s, N) * fluid_mask
603632
rho = rho + self.dt * drhodt
@@ -687,6 +716,7 @@ def forward(state, neighbors):
687716
mask,
688717
n_w[j_s],
689718
g_ext[i_s],
719+
u_tilde[j_s],
690720
)
691721
dudt = ops.segment_sum(out, i_s, N)
692722

tests/test_pf2d.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,11 @@ def get_solution(data_path, t_dimless, y_axis):
103103
return solutions
104104

105105

106-
@pytest.mark.parametrize("tvf, solver", [(0.0, "SPH"), (1.0, "SPH")]) # (0.0, "RIE")
106+
@pytest.mark.parametrize("tvf, solver", [(0.0, "SPH"), (1.0, "SPH"), (0.0, "RIE")])
107107
def test_pf2d(tvf, solver, tmp_path, setup_simulation):
108108
"""Test whether the poiseuille flow simulation matches the analytical solution"""
109109
y_axis, t_dimless, ref_solutions = setup_simulation
110110
data_path = run_simulation(tmp_path, tvf, solver)
111-
# print(f"tmp_path = {tmp_path}, subdirs = {subdirs}")
112111
solutions = get_solution(data_path, t_dimless, y_axis)
113-
# print(f"solution: {solutions[-1]} \nref_solution: {ref_solutions[-1]}")
114112
for sol, ref_sol in zip(solutions, ref_solutions):
115113
assert np.allclose(sol, ref_sol, atol=1e-2), "Velocity profile does not match."

validation/pf2d.sh

+2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
# Generate data
77
python main.py config=cases/pf.yaml solver.tvf=1.0 io.data_path=data_valid/pf2d_tvf/
88
python main.py config=cases/pf.yaml solver.tvf=0.0 io.data_path=data_valid/pf2d_notvf/
9+
python main.py config=cases/pf.yaml solver.tvf=0.0 solver.name=RIE solver.density_evolution=True io.data_path=data_valid/pf2d_Rie/
910

1011
# Run validation script
1112
python validation/validate.py --case=2D_PF --src_dir=data_valid/pf2d_tvf/
1213
python validation/validate.py --case=2D_PF --src_dir=data_valid/pf2d_notvf/
14+
python validation/validate.py --case=2D_PF --src_dir=data_valid/pf2d_Rie/

0 commit comments

Comments
 (0)