Skip to content

Commit

Permalink
Merge branch 'main' into kernel-1D-support
Browse files Browse the repository at this point in the history
  • Loading branch information
LasNikas committed Oct 23, 2023
2 parents 1daf38e + b4fd4f4 commit be97f07
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 41 deletions.
80 changes: 80 additions & 0 deletions src/general/corrections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,83 @@ function compute_correction_values!(system, system_index, v, u, v_ode, u_ode, se
dw_gamma[i, particle] /= kernel_correction_coefficient[particle]
end
end

@doc raw"""
GradientCorrection()
Compute the corrected gradient of particle interactions based on their relative positions.
# Mathematical Details
Given the standard SPH representation, the gradient of a field A at particle i is given by:
```math
\nabla A_a = \sum_b m_b \frac{A_b - A_a}{\rho_b} \nabla_{r_a} W(\Vert r_a - r_b \Vert, h)
```
Where:
- $m_b$ is the mass of particle $b$.
- $rho_b$ is the density of particle $b$.
The gradient correction, as commonly proposed, involves multiplying this gradient with a correction matrix $L$:
```math
\nabla^\tilde A_i = L_i \nabla A_i
```
The correction matrix $L_i$ is computed based on the provided particle configuration,
aiming to make the corrected gradient more accurate, especially near domain boundaries.
# Notes:
- Stability issues as especially when particles separate into small clusters.
- Doubles the computational effort.
## References:
- J. Bonet, T.-S.L. Lok.
"Variational and momentum preservation aspects of Smooth Particle Hydrodynamic formulations".
In: Computer Methods in Applied Mechanics and Engineering 180 (1999), pages 97-115.
[doi: 10.1016/S0045-7825(99)00051-1](https://doi.org/10.1016/S0045-7825(99)00051-1)
- Mihai Basa, Nathan Quinlan, Martin Lastiwka.
"Robustness and accuracy of SPH formulations for viscous flow".
In: International Journal for Numerical Methods in Fluids 60 (2009), pages 1127-1148.
[doi: 10.1002/fld.1927](https://doi.org/10.1002/fld.1927)
"""
struct GradientCorrection end

function compute_gradient_correction_matrix!(corr_matrix, neighborhood_search, system,
coordinates)
(; mass, material_density) = system

set_zero!(corr_matrix)

# Loop over all pairs of particles and neighbors within the kernel cutoff.
for_particle_neighbor(system, system,
coordinates, coordinates,
neighborhood_search;
particles=eachparticle(system)) do particle, neighbor,
pos_diff,
distance
# Only consider particles with a distance > 0.
distance < sqrt(eps()) && return

volume = mass[neighbor] / material_density[neighbor]

grad_kernel = smoothing_kernel_grad(system, pos_diff, distance)
result = volume * grad_kernel * pos_diff'

@inbounds for j in 1:ndims(system), i in 1:ndims(system)
corr_matrix[i, j, particle] -= result[i, j]
end
end

@threaded for particle in eachparticle(system)
L = correction_matrix(system, particle)
result = inv(L)

@inbounds for j in 1:ndims(system), i in 1:ndims(system)
corr_matrix[i, j, particle] = result[i, j]
end
end

return corr_matrix
end
44 changes: 3 additions & 41 deletions src/schemes/solid/total_lagrangian_sph/system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,49 +250,11 @@ end
function initialize!(system::TotalLagrangianSPHSystem, neighborhood_search)
(; correction_matrix) = system

# Calculate kernel correction matrix
calc_correction_matrix!(correction_matrix, neighborhood_search, system)
end

function calc_correction_matrix!(corr_matrix, neighborhood_search, system)
(; mass, material_density) = system

set_zero!(corr_matrix)

# Calculate kernel correction matrix
initial_coords = initial_coordinates(system)

# Loop over all pairs of particles and neighbors within the kernel cutoff.
for_particle_neighbor(system, system,
initial_coords, initial_coords,
neighborhood_search;
particles=eachparticle(system)) do particle, neighbor,
initial_pos_diff,
initial_distance
# Only consider particles with a distance > 0.
initial_distance < sqrt(eps()) && return

volume = mass[neighbor] / material_density[neighbor]

grad_kernel = smoothing_kernel_grad(system, initial_pos_diff,
initial_distance)
result = volume * grad_kernel * initial_pos_diff'

@inbounds for j in 1:ndims(system), i in 1:ndims(system)
corr_matrix[i, j, particle] -= result[i, j]
end
end

@threaded for particle in eachparticle(system)
L = correction_matrix(system, particle)
result = inv(L)

@inbounds for j in 1:ndims(system), i in 1:ndims(system)
corr_matrix[i, j, particle] = result[i, j]
end
end

return corr_matrix
# Calculate kernel correction matrix
compute_gradient_correction_matrix!(correction_matrix, neighborhood_search, system,
initial_coords)
end

function update_positions!(system::TotalLagrangianSPHSystem, system_index, v, u,
Expand Down

0 comments on commit be97f07

Please sign in to comment.