Skip to content

Commit e9874a5

Browse files
author
LasNikas
committed
Merge branch 'main' into open-boundaries-nhs-fix-patch-2
2 parents 2255d87 + d4f8af7 commit e9874a5

File tree

6 files changed

+91
-19
lines changed

6 files changed

+91
-19
lines changed

docs/src/preprocessing/preprocessing.md

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Sampling of Geometries
1+
# [Sampling of Geometries](@id sampling_of_geometries)
22

33
Generating the initial configuration of a simulation requires filling volumes (3D) or surfaces (2D) of complex geometries with particles.
44
The algorithm to sample a complex geometry should be robust and fast,
@@ -256,9 +256,57 @@ Modules = [TrixiParticles]
256256
Pages = [joinpath("preprocessing", "geometries", "io.jl")]
257257
```
258258

259-
# Particle Packing
259+
# [Particle Packing](@id particle_packing)
260+
To obtain a body-fitted and isotropic particle distribution, an initial configuration (see [Sampling of Geometries](@ref sampling_of_geometries)) is first generated. This configuration is then packed using a [`ParticlePackingSystem`](@ref).
261+
The preprocessing pipeline consists of the following steps:
262+
263+
- Load geometry: Fig. 1, [`load_geometry`](@ref).
264+
- Compute the signed distance field (SDF): Fig. 2, [`SignedDistanceField`](@ref).
265+
- Generate boundary particles: Fig. 3, [`sample_boundary`](@ref).
266+
- Initial sampling of the interior particles with inside-outside segmentation: Fig. 4, [`ComplexShape`](@ref).
267+
- Pack the initial configuration of interior and boundary particles (Fig. 5): Fig. 6, [`ParticlePackingSystem`](@ref).
268+
269+
The input data can either be a 3D triangulated surface mesh represented in STL format or a 2D polygonal traversal of the geometry (see [`load_geometry`](@ref)).
270+
The second step involves generating the SDF (see [`SignedDistanceField`](@ref)), which is necessary for the final packing step as it requires a surface detection.
271+
The SDF is illustrated in Fig. 2, where the distances to the surface of the geometry are visualized as a color map.
272+
As shown, the SDF is computed only within a narrow band around the geometry’s surface, enabling a face-based neighborhood search (NHS) to be used exclusively during this step.
273+
In the third step, the initial configuration of the boundary particles is generated (orange particles in Fig. 3).
274+
Boundary particles are created by copying the positions of SDF points located outside the geometry but within a predefined boundary thickness (see [`sample_boundary`](@ref)).
275+
In the fourth step, the initial configuration of the interior particles (green particles in Fig. 4) is generated using the hierarchical winding number approach (see [Hierarchical Winding](@ref hierarchical_winding)).
276+
After steps **1** through **4**, the initial configuration of both interior and boundary particles is obtained, as illustrated in Fig. 5.
277+
The interface of the geometry surface is not well resolved with the initial particle configuration.
278+
Thus, in the final step, a packing algorithm by Zhu et al. [Zhu2021](@cite) is applied utilizing the SDF to simultaneously optimize the positions of both interior and boundary particles,
279+
yielding an isotropic distribution while accurately preserving the geometry surface, as illustrated in Fig. 6.
280+
281+
```@raw html
282+
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
283+
<figure style="margin: 0; text-align: center;">
284+
<img src="https://github.com/user-attachments/assets/7fe9d1f1-1633-4377-8b97-a4d1778aee07" alt="geometry" style="max-width: 200px;">
285+
<figcaption>(1) Geometry representation</figcaption>
286+
</figure>
287+
<figure style="margin: 0; text-align: center;">
288+
<img src="https://github.com/user-attachments/assets/2b79188c-3148-49f1-8337-718721851bf5" alt="sdf" style="max-width: 200px;">
289+
<figcaption>(2) Signed distances to the surface</figcaption>
290+
</figure>
291+
<figure style="margin: 0; text-align: center;">
292+
<img src="https://github.com/user-attachments/assets/1501718f-d1f5-4f14-b1bc-2a2e581db476" alt="boundary" style="max-width: 200px;">
293+
<figcaption>(3) Boundary particles</figcaption>
294+
</figure>
295+
<figure style="margin: 0; text-align: center;">
296+
<img src="https://github.com/user-attachments/assets/f7376b15-324a-4da1-bb59-db01c7bd6620" alt="interior" style="max-width: 200px;">
297+
<figcaption>(4) Interior particles</figcaption>
298+
</figure>
299+
<figure style="margin: 0; text-align: center;">
300+
<img src="https://github.com/user-attachments/assets/4be889d6-e70a-4c5e-bef2-0071ea4d898c" alt="initial_config" style="max-width: 200px;">
301+
<figcaption>(5) Initial configuration</figcaption>
302+
</figure>
303+
<figure style="margin: 0; text-align: center;">
304+
<img src="https://github.com/user-attachments/assets/0f7aba29-3cf7-4ec1-8c95-841e72fe620d" alt="packed_config" style="max-width: 200px;">
305+
<figcaption>(6) Packed configuration</figcaption>
306+
</figure>
307+
</div>
308+
```
260309

261-
TODO
262310

263311
```@autodocs
264312
Modules = [TrixiParticles]

docs/src/refs.bib

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,3 +735,17 @@ @book{Poling2001
735735
publisher = {McGraw-Hill},
736736
address = {New York}
737737
}
738+
739+
@article{Zhu2021,
740+
author = {Zhu, Yujie and Zhang, Chi and Yu, Yongchuan and Hu, Xiangyu},
741+
journal = {Journal of Hydrodynamics},
742+
title = {A {CAD}-compatible body-fitted particle generator for arbitrarily complex geometry and its application to wave-structure interaction},
743+
year = {2021},
744+
issn = {1878-0342},
745+
month = apr,
746+
number = {2},
747+
pages = {195--206},
748+
volume = {33},
749+
doi = {10.1007/s42241-021-0031-y},
750+
publisher = {Springer Science and Business Media LLC}
751+
}

src/preprocessing/particle_packing/system.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
"""
22
ParticlePackingSystem(shape::InitialCondition;
3-
signed_distance_field::SignedDistanceField,
3+
signed_distance_field::Union{SignedDistanceField, Nothing},
44
smoothing_kernel=SchoenbergQuinticSplineKernel{ndims(shape)}(),
55
smoothing_length=shape.particle_spacing,
66
smoothing_length_interpolation=smoothing_length,
77
is_boundary=false, boundary_compress_factor=1,
88
neighborhood_search=GridNeighborhoodSearch{ndims(shape)}(),
9-
background_pressure, tlsph=true, fixed_system=false)
9+
background_pressure, tlsph=false, fixed_system=false)
1010
1111
System to generate body-fitted particles for complex shapes.
12-
For more information on the methods, see description below.
12+
For more information on the methods, see [particle packing](@ref particle_packing).
1313
1414
# Arguments
1515
- `shape`: [`InitialCondition`](@ref) to be packed.
@@ -23,7 +23,7 @@ For more information on the methods, see description below.
2323
as for fluids. When `tlsph=true`, particles will be placed
2424
on the boundary of the shape.
2525
- `is_boundary`: When `shape` is inside the geometry that was used to create
26-
`signed_distance_field, set `is_boundary=false`.
26+
`signed_distance_field`, set `is_boundary=false`.
2727
Otherwise (`shape` is the sampled boundary), set `is_boundary=true`.
2828
The thickness of the boundary is specified by creating
2929
`signed_distance_field` with:
@@ -40,12 +40,19 @@ For more information on the methods, see description below.
4040
the signed distance from a particle to a face is required.
4141
The precalculated signed distances will be interpolated
4242
to each particle during the packing procedure.
43+
Set `signed_distance_field=nothing` when packing with a fixed system
44+
(see `fixed_system` description above).
4345
- `smoothing_kernel`: Smoothing kernel to be used for this system.
4446
See [Smoothing Kernels](@ref smoothing_kernel).
4547
- `smoothing_length`: Smoothing length to be used for the gradient estimation.
4648
See [Smoothing Kernels](@ref smoothing_kernel).
4749
- `smoothing_length_interpolation`: Smoothing length to be used for interpolating the `SignedDistanceField` information.
4850
The default is `smoothing_length_interpolation = smoothing_length`.
51+
- `boundary_compress_factor`: Factor to compress the boundary particles by reducing the boundary thickness by a factor of `boundary_compress_factor`.
52+
The default value is `1`, which means no compression.
53+
Compression can be useful for highly convex geometries,
54+
where the boundary volume increases significantly while the mass of the boundary particles remains constant.
55+
Recommended values are `0.8` or `0.9`.
4956
"""
5057
struct ParticlePackingSystem{S, F, NDIMS, ELTYPE <: Real, PR, C, AV,
5158
IC, M, D, K, N, SD, UCU} <: FluidSystem{NDIMS}
@@ -95,8 +102,7 @@ struct ParticlePackingSystem{S, F, NDIMS, ELTYPE <: Real, PR, C, AV,
95102
end
96103

97104
function ParticlePackingSystem(shape::InitialCondition;
98-
signed_distance_field::Union{SignedDistanceField,
99-
Nothing},
105+
signed_distance_field::Union{SignedDistanceField, Nothing},
100106
smoothing_kernel=SchoenbergQuinticSplineKernel{ndims(shape)}(),
101107
smoothing_length=shape.particle_spacing,
102108
smoothing_length_interpolation=smoothing_length,

src/schemes/fluid/entropically_damped_sph/system.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ function update_final!(system::EntropicallyDampedSPHSystem, v, u, v_ode, u_ode,
306306
compute_curvature!(system, surface_tension, v, u, v_ode, u_ode, semi, t)
307307
compute_stress_tensors!(system, surface_tension, v, u, v_ode, u_ode, semi, t)
308308
update_average_pressure!(system, system.transport_velocity, v_ode, u_ode, semi)
309+
310+
# Check that TVF is only used together with `UpdateCallback`
311+
check_tvf_configuration(system, system.transport_velocity, v, u, v_ode, u_ode, semi, t;
312+
update_from_callback)
309313
end
310314

311315
function update_average_pressure!(system, ::Nothing, v_ode, u_ode, semi)

src/schemes/fluid/transport_velocity.jl

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,19 +165,15 @@ function update_callback_used!(system, transport_velocity)
165165
system.cache.update_callback_used[] = true
166166
end
167167

168-
function update_final!(system::FluidSystem, v, u, v_ode, u_ode, semi, t;
169-
update_from_callback=false)
170-
update_final!(system, system.transport_velocity,
171-
v, u, v_ode, u_ode, semi, t; update_from_callback)
172-
end
173-
174-
function update_final!(system::FluidSystem, ::Nothing,
175-
v, u, v_ode, u_ode, semi, t; update_from_callback=false)
168+
function check_tvf_configuration(system::FluidSystem, ::Nothing,
169+
v, u, v_ode, u_ode, semi, t; update_from_callback=false)
176170
return system
177171
end
178172

179-
function update_final!(system::FluidSystem, ::TransportVelocityAdami,
180-
v, u, v_ode, u_ode, semi, t; update_from_callback=false)
173+
function check_tvf_configuration(system::FluidSystem, ::TransportVelocityAdami,
174+
v, u, v_ode, u_ode, semi, t; update_from_callback=false)
175+
# The `UpdateCallback` will set `system.cache.update_callback_used[]` to `true`
176+
# in the initialization. However, other callbacks might update the system first, hence `update_from_callback`.
181177
if !update_from_callback && !(system.cache.update_callback_used[])
182178
throw(ArgumentError("`UpdateCallback` is required when using `TransportVelocityAdami`"))
183179
end

src/schemes/fluid/weakly_compressible_sph/system.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ function update_final!(system::WeaklyCompressibleSPHSystem, v, u, v_ode, u_ode,
304304
# Surface normal of neighbor and boundary needs to have been calculated already
305305
compute_curvature!(system, surface_tension, v, u, v_ode, u_ode, semi, t)
306306
compute_stress_tensors!(system, surface_tension, v, u, v_ode, u_ode, semi, t)
307+
308+
# Check that TVF is only used together with `UpdateCallback`
309+
check_tvf_configuration(system, system.transport_velocity, v, u, v_ode, u_ode, semi, t;
310+
update_from_callback)
307311
end
308312

309313
function kernel_correct_density!(system::WeaklyCompressibleSPHSystem, v, u, v_ode, u_ode,

0 commit comments

Comments
 (0)