|
1 | 1 | # Unpack the neighboring systems viscosity to dispatch on the viscosity type. |
2 | 2 | # This function is only necessary to allow `nothing` as viscosity. |
3 | 3 | # Otherwise, we could just apply the viscosity as a function directly. |
4 | | -@propagate_inbounds function dv_viscosity_tlsph(system, v_system, particle, neighbor, |
5 | | - current_pos_diff, current_distance, |
6 | | - m_a, m_b, rho_a, rho_b, grad_kernel) |
| 4 | +@propagate_inbounds function dv_viscosity_tlsph!(dv_particle, system, v_system, |
| 5 | + particle, neighbor, |
| 6 | + current_pos_diff, current_distance, |
| 7 | + m_a, m_b, rho_a, rho_b, grad_kernel) |
7 | 8 | viscosity = system.viscosity |
8 | 9 |
|
9 | | - return dv_viscosity_tlsph(viscosity, system, v_system, particle, neighbor, |
10 | | - current_pos_diff, current_distance, |
11 | | - m_a, m_b, rho_a, rho_b, grad_kernel) |
| 10 | + return dv_viscosity_tlsph!(dv_particle, viscosity, system, v_system, |
| 11 | + particle, neighbor, current_pos_diff, current_distance, |
| 12 | + m_a, m_b, rho_a, rho_b, grad_kernel) |
12 | 13 | end |
13 | 14 |
|
14 | | -@propagate_inbounds function dv_viscosity_tlsph(viscosity, system, |
15 | | - v_system, particle, neighbor, |
16 | | - current_pos_diff, current_distance, |
17 | | - m_a, m_b, rho_a, rho_b, grad_kernel) |
18 | | - return viscosity(system, v_system, particle, neighbor, |
| 15 | +@propagate_inbounds function dv_viscosity_tlsph!(dv_particle, viscosity, system, |
| 16 | + v_system, particle, neighbor, |
| 17 | + current_pos_diff, current_distance, |
| 18 | + m_a, m_b, rho_a, rho_b, grad_kernel) |
| 19 | + return viscosity(dv_particle, system, v_system, particle, neighbor, |
19 | 20 | current_pos_diff, current_distance, |
20 | 21 | m_a, m_b, rho_a, rho_b, grad_kernel) |
21 | 22 | end |
22 | 23 |
|
23 | | -@inline function dv_viscosity_tlsph(viscosity::Nothing, system, |
24 | | - v_system, particle, neighbor, |
25 | | - current_pos_diff, current_distance, |
26 | | - m_a, m_b, rho_a, rho_b, grad_kernel) |
| 24 | +@inline function dv_viscosity_tlsph!(dv_particle, viscosity::Nothing, system, |
| 25 | + v_system, particle, neighbor, |
| 26 | + current_pos_diff, current_distance, |
| 27 | + m_a, m_b, rho_a, rho_b, grad_kernel) |
27 | 28 | return zero(current_pos_diff) |
28 | 29 | end |
29 | 30 |
|
30 | 31 | # Applying the viscosity according to Lin et al. (2015): |
31 | 32 | # "Geometrically nonlinear analysis of two-dimensional structures using an improved |
32 | 33 | # smoothed particle hydrodynamics method" |
33 | | -@propagate_inbounds function (viscosity::ArtificialViscosityMonaghan)(system::TotalLagrangianSPHSystem, |
| 34 | +@propagate_inbounds function (viscosity::ArtificialViscosityMonaghan)(dv_particle, |
| 35 | + system::TotalLagrangianSPHSystem, |
34 | 36 | v_system, |
35 | 37 | particle, neighbor, |
36 | 38 | current_pos_diff, |
37 | 39 | current_distance, |
38 | 40 | m_a, m_b, rho_a, |
39 | 41 | rho_b, grad_kernel) |
40 | | - rho_mean = (rho_a + rho_b) / 2 |
41 | | - |
42 | 42 | v_a = current_velocity(v_system, system, particle) |
43 | 43 | v_b = current_velocity(v_system, system, neighbor) |
44 | 44 | v_diff = v_a - v_b |
45 | 45 |
|
46 | | - smoothing_length_particle = smoothing_length(system, particle) |
47 | | - smoothing_length_neighbor = smoothing_length(system, neighbor) |
48 | | - smoothing_length_average = (smoothing_length_particle + smoothing_length_neighbor) / 2 |
| 46 | + # v_ab ⋅ r_ab |
| 47 | + vr = dot(v_diff, current_pos_diff) |
49 | 48 |
|
50 | | - # Compute bulk modulus from Young's modulus and Poisson's ratio. |
51 | | - # See the table at the end of https://en.wikipedia.org/wiki/Lam%C3%A9_parameters |
52 | | - E = young_modulus(system, particle) |
53 | | - K = E / (ndims(system) * (1 - 2 * poisson_ratio(system, particle))) |
| 49 | + # Monaghan 2005 p. 1741 (doi: 10.1088/0034-4885/68/8/r01): |
| 50 | + # "In the case of shock tube problems, it is usual to turn the viscosity on for |
| 51 | + # approaching particles and turn it off for receding particles. In this way, the |
| 52 | + # viscosity is used for shocks and not rarefactions." |
| 53 | + if vr < 0 |
| 54 | + # Compute bulk modulus from Young's modulus and Poisson's ratio. |
| 55 | + # See the table at the end of https://en.wikipedia.org/wiki/Lam%C3%A9_parameters |
| 56 | + E = young_modulus(system, particle) |
| 57 | + K = E / (ndims(system) * (1 - 2 * poisson_ratio(system, particle))) |
54 | 58 |
|
55 | | - # Newton–Laplace equation |
56 | | - sound_speed = sqrt(K / rho_a) |
| 59 | + # Newton–Laplace equation |
| 60 | + sound_speed = sqrt(K / rho_a) |
57 | 61 |
|
58 | | - # This is not needed for `ArtificialViscosityMonaghan` |
59 | | - nu_a = nu_b = 0 |
| 62 | + h_a = smoothing_length(system, particle) |
| 63 | + h_b = smoothing_length(system, neighbor) |
| 64 | + h = (h_a + h_b) / 2 |
60 | 65 |
|
61 | | - pi_ab = viscosity(sound_speed, v_diff, current_pos_diff, current_distance, |
62 | | - rho_mean, rho_a, rho_b, smoothing_length_average, |
63 | | - grad_kernel, nu_a, nu_b) |
| 66 | + rho_mean = (rho_a + rho_b) / 2 |
64 | 67 |
|
65 | | - # See eq. 26 of Lin et al. (2015) |
66 | | - F = deformation_gradient(system, particle) |
| 68 | + (; alpha, beta, epsilon) = viscosity |
| 69 | + mu = h * vr / (current_distance^2 + epsilon * h^2) |
| 70 | + c = sound_speed |
| 71 | + pi_ab = (alpha * c * mu + beta * mu^2) / rho_mean * grad_kernel |
67 | 72 |
|
68 | | - if abs(det(F)) < 1.0f-9 |
69 | | - return zero(grad_kernel) |
| 73 | + F = deformation_gradient(system, particle) |
| 74 | + det_F = det(F) |
| 75 | + if abs(det_F) < 1.0f-9 |
| 76 | + return dv_particle |
| 77 | + end |
| 78 | + # See eq. 26 of Lin et al. (2015) |
| 79 | + dv_particle[] += m_b * det_F * inv(F)' * pi_ab |
70 | 80 | end |
71 | 81 |
|
72 | | - return m_b * det(F) * inv(F)' * pi_ab |
| 82 | + return dv_particle |
73 | 83 | end |
0 commit comments