Skip to content

Commit d99abe1

Browse files
authored
Merge branch 'main' into test-1.12
2 parents f0d0527 + 29e7609 commit d99abe1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1474
-578
lines changed

.github/workflows/SpellCheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ jobs:
1010
- name: Checkout Actions Repository
1111
uses: actions/checkout@v4
1212
- name: Check spelling
13-
uses: crate-ci/typos@v1.31.2
13+
uses: crate-ci/typos@v1.32.0

NEWS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ TrixiParticles.jl follows the interpretation of
44
[semantic versioning (semver)](https://julialang.github.io/Pkg.jl/dev/compatibility/#Version-specifier-format-1)
55
used in the Julia ecosystem. Notable changes will be documented in this file for human readability.
66

7+
## Version 0.3.1
8+
9+
### Features
10+
11+
- With all CPU backends, a new array type is used for the integration array, which defines
12+
broadcasting to be multithreaded, leading to speedups of up to 5x with large thread counts
13+
when combined with thread pinning (#722).
14+
715
## Version 0.3
816

917
### API Changes

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ KernelAbstractions = "0.9"
5454
MuladdMacro = "0.2"
5555
OrdinaryDiffEq = "6.91"
5656
OrdinaryDiffEqCore = "1"
57-
PointNeighbors = "0.6.1"
57+
PointNeighbors = "0.6.3"
5858
Polyester = "0.7.10"
5959
ReadVTK = "0.2"
6060
RecipesBase = "1"

docs/src/gpu.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ Unlike the default cell list, which assumes an unbounded domain,
1313
this cell list requires a bounding box for the domain.
1414
For simulations that are bounded by a closed tank, we can simply use the boundary
1515
of the tank to obtain the bounding box as follows.
16-
```jldoctest gpu; output=false, setup=:(using TrixiParticles; trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "hydrostatic_water_column_2d.jl"), sol=nothing))
16+
```jldoctest gpu; output=false, filter = r"FullGridCellList{PointNeighbors.DynamicVectorOfVectors{.*", setup=:(using TrixiParticles; trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "hydrostatic_water_column_2d.jl"), sol=nothing))
1717
min_corner = minimum(tank.boundary.coordinates, dims=2)
1818
max_corner = maximum(tank.boundary.coordinates, dims=2)
1919
cell_list = FullGridCellList(; min_corner, max_corner)
2020
2121
# output
22-
FullGridCellList{PointNeighbors.DynamicVectorOfVectors{Int32, Matrix{Int32}, Vector{Int32}, Base.RefValue{Int32}}, Nothing, SVector{2, Float64}, SVector{2, Float64}}(Vector{Int32}[], nothing, [-0.12500000000000003, -0.12500000000000003], [1.125, 1.125])
22+
FullGridCellList{PointNeighbors.DynamicVectorOfVectors{...}(...)
23+
2324
```
2425

2526
We then need to pass this cell list to the neighborhood search and the neighborhood search

docs/src/preprocessing/preprocessing.md

Lines changed: 96 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,
@@ -250,15 +250,108 @@ Pages = [joinpath("preprocessing", "point_in_poly", "winding_number_hormann.jl")
250250
Modules = [TrixiParticles]
251251
Pages = [joinpath("preprocessing", "point_in_poly", "winding_number_jacobson.jl")]
252252
```
253+
# [Read geometries from file](@id read_geometries_from_file)
254+
Geometries can be imported using the [`load_geometry`](@ref) function.
255+
- For 3D geometries, we support the binary (`.stl`) format.
256+
- For 2D geometries, the recommended format is DXF (`.dxf`), with optional support for a simple ASCII (`.asc`) format.
257+
258+
## ASCII Format (.asc)
259+
An .asc file contains a list of 2D coordinates, space-delimited, one point per line,
260+
where the first column are the x values and the second the y values.
261+
For example:
262+
```plaintext
263+
# ASCII
264+
0.0 0.0
265+
1.0 0.0
266+
1.0 1.0
267+
0.0 1.0
268+
```
269+
It is the user’s responsibility to ensure the points are ordered correctly.
270+
This format is easy to generate and inspect manually.
271+
272+
## DXF Format (.dxf) – recommended
273+
The DXF (Drawing Exchange Format) is a widely-used CAD format for 2D and 3D data.
274+
We recommend this format for defining 2D polygonal.
275+
Only DXF entities of type `LINE` or `POLYLINE` are supported.
276+
To create DXF files from scratch, we recommend using the open-source tool [FreeCAD](https://www.freecad.org/).
277+
For a less technical approach, we recommend using [Inkscape](https://inkscape.org/) to create SVG files and then export them as DXF.
278+
279+
### Creating DXF Files with FreeCAD
280+
281+
- Open FreeCAD and create a new document.
282+
- Switch to the Sketcher workbench and create a new sketch.
283+
- Choose the XY-plane orientation and draw your geometry.
284+
- Select the object to be exported.
285+
- Go to "File > Export..." and choose "AutoDesk DXF (*.dxf)" as the format.
286+
- Ensure the following Import-Export options are enabled:
287+
- "Use legacy Python exporter".
288+
- "Project exported objects along current view direction".
289+
290+
### Creating DXF Files with Inkscape
291+
SVG vector graphics can also be used as a basis for geometry.
292+
Use Inkscape to open or create the SVG.
293+
You can simply draw a Bezier curve by pressing "B" on your keyboard.
294+
We reommend the mode "Create spiro paths" for a smooth curve.
295+
Select the relevant path and export it as DXF:
296+
- Go to "File > Save As...".
297+
- Choose "Desktop Cutting Plotter (AutoCAD DXF R12)(*.dxf)" format.
253298

254299
```@autodocs
255300
Modules = [TrixiParticles]
256301
Pages = [joinpath("preprocessing", "geometries", "io.jl")]
257302
```
258303

259-
# Particle Packing
304+
# [Particle Packing](@id particle_packing)
305+
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).
306+
The preprocessing pipeline consists of the following steps:
307+
308+
- Load geometry: Fig. 1, [`load_geometry`](@ref).
309+
- Compute the signed distance field (SDF): Fig. 2, [`SignedDistanceField`](@ref).
310+
- Generate boundary particles: Fig. 3, [`sample_boundary`](@ref).
311+
- Initial sampling of the interior particles with inside-outside segmentation: Fig. 4, [`ComplexShape`](@ref).
312+
- Pack the initial configuration of interior and boundary particles (Fig. 5): Fig. 6, [`ParticlePackingSystem`](@ref).
313+
314+
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)).
315+
The second step involves generating the SDF (see [`SignedDistanceField`](@ref)), which is necessary for the final packing step as it requires a surface detection.
316+
The SDF is illustrated in Fig. 2, where the distances to the surface of the geometry are visualized as a color map.
317+
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.
318+
In the third step, the initial configuration of the boundary particles is generated (orange particles in Fig. 3).
319+
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)).
320+
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)).
321+
After steps **1** through **4**, the initial configuration of both interior and boundary particles is obtained, as illustrated in Fig. 5.
322+
The interface of the geometry surface is not well resolved with the initial particle configuration.
323+
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,
324+
yielding an isotropic distribution while accurately preserving the geometry surface, as illustrated in Fig. 6.
325+
326+
```@raw html
327+
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
328+
<figure style="margin: 0; text-align: center;">
329+
<img src="https://github.com/user-attachments/assets/7fe9d1f1-1633-4377-8b97-a4d1778aee07" alt="geometry" style="max-width: 200px;">
330+
<figcaption>(1) Geometry representation</figcaption>
331+
</figure>
332+
<figure style="margin: 0; text-align: center;">
333+
<img src="https://github.com/user-attachments/assets/2b79188c-3148-49f1-8337-718721851bf5" alt="sdf" style="max-width: 200px;">
334+
<figcaption>(2) Signed distances to the surface</figcaption>
335+
</figure>
336+
<figure style="margin: 0; text-align: center;">
337+
<img src="https://github.com/user-attachments/assets/1501718f-d1f5-4f14-b1bc-2a2e581db476" alt="boundary" style="max-width: 200px;">
338+
<figcaption>(3) Boundary particles</figcaption>
339+
</figure>
340+
<figure style="margin: 0; text-align: center;">
341+
<img src="https://github.com/user-attachments/assets/f7376b15-324a-4da1-bb59-db01c7bd6620" alt="interior" style="max-width: 200px;">
342+
<figcaption>(4) Interior particles</figcaption>
343+
</figure>
344+
<figure style="margin: 0; text-align: center;">
345+
<img src="https://github.com/user-attachments/assets/4be889d6-e70a-4c5e-bef2-0071ea4d898c" alt="initial_config" style="max-width: 200px;">
346+
<figcaption>(5) Initial configuration</figcaption>
347+
</figure>
348+
<figure style="margin: 0; text-align: center;">
349+
<img src="https://github.com/user-attachments/assets/0f7aba29-3cf7-4ec1-8c95-841e72fe620d" alt="packed_config" style="max-width: 200px;">
350+
<figcaption>(6) Packed configuration</figcaption>
351+
</figure>
352+
</div>
353+
```
260354

261-
TODO
262355

263356
```@autodocs
264357
Modules = [TrixiParticles]

docs/src/refs.bib

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,17 @@ @Article{Sun2017
648648
publisher = {Elsevier BV},
649649
}
650650

651+
@article{Sun2018,
652+
author = {Sun, P. N. and Colagrossi, A. and Marrone, S. and Antuono, M. and Zhang, A. M.},
653+
title = {Multi-resolution Delta-plus-{SPH} with tensile instability control: Towards high Reynolds number flows},
654+
journal = {Computer Physics Communications},
655+
volume = {224},
656+
year = {2018},
657+
issn = {0010-4655},
658+
pages = {63--80},
659+
doi = {10.1016/j.cpc.2017.11.016},
660+
}
661+
651662
@Article{Tafuni2018,
652663
author = {A. Tafuni and J.M. Dom{\'{\i}}nguez and R. Vacondio and A.J.C. Crespo},
653664
journal = {Computer Methods in Applied Mechanics and Engineering},
@@ -723,4 +734,18 @@ @book{Poling2001
723734
year = {2001},
724735
publisher = {McGraw-Hill},
725736
address = {New York}
726-
}
737+
}
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+
}

docs/src/systems/fluid.md

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# [Fluid Models](@id fluid_models)
22

33
Currently available fluid methods are the [weakly compressible SPH method](@ref wcsph) and the
4-
[entropically damped artificial compressibility for SPH](@ref edac).
5-
This page lists models and techniques that apply to both of these methods.
4+
[entropically damped artificial compressibility for SPH](@ref edac).
5+
This page lists models and techniques that apply to both of these methods.
66

77
## [Viscosity](@id viscosity_sph)
88

@@ -58,21 +58,19 @@ by Balsara ([Balsara1995](@cite)) or Morris ([Morris1997](@cite)).
5858
The force exerted by particle `b` on particle `a` due to artificial viscosity is given by:
5959

6060
```math
61-
\mathbf{F}_{ab}^{\text{AV}} = - m_a m_b \Pi_{ab} \nabla W_{ab}
61+
F_{ab}^{\text{AV}} = - m_a m_b \Pi_{ab} \nabla W_{ab}
6262
```
6363

6464
where:
6565

66-
- `\Pi_{ab}` is the artificial viscosity term defined as:
67-
68-
```math
69-
\Pi_{ab} =
70-
\begin{cases}
71-
-\frac{\alpha c \mu_{ab} + \beta \mu_{ab}^2}{\bar{\rho}_{ab}} & \text{if } \mathbf{v}_{ab} \cdot \mathbf{r}_{ab} < 0, \\
72-
0 & \text{otherwise}
73-
\end{cases}
74-
```
75-
66+
- ``\Pi_{ab}`` is the artificial viscosity term defined as:
67+
```math
68+
\Pi_{ab} =
69+
\begin{cases}
70+
-\frac{\alpha c \mu_{ab} + \beta \mu_{ab}^2}{\bar{\rho}_{ab}} & \text{if } \mathbf{v}_{ab} \cdot \mathbf{r}_{ab} < 0, \\
71+
0 & \text{otherwise}
72+
\end{cases}
73+
```
7674
- ``\alpha`` and ``\beta`` are viscosity parameters,
7775
- ``c`` is the local speed of sound,
7876
- ``\bar{\rho}_{ab}`` is the arithmetic mean of the densities of particles ``a`` and ``b``.
@@ -361,7 +359,7 @@ with:
361359
This divergence can be computed numerically in the SPH framework as
362360

363361
```math
364-
\sum_b \frac{m_b}{\rho_a \rho_b} (S_a + S_b) \nabla W_{ab}
362+
\sum_b \frac{m_b}{\rho_a \rho_b} (S_a + S_b) \nabla W_{ab}
365363
```
366364

367365
#### Advantages and limitations

docs/src/systems/weakly_compressible_sph.md

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ pressure field. It is highly recommended to use density diffusion when using WCS
5454
All density diffusion terms extend the continuity equation (see [`ContinuityDensity`](@ref))
5555
by an additional term
5656
```math
57-
\frac{\mathrm{d}\rho_a}{\mathrm{d}t} = \sum_{b} m_b v_{ab} \cdot \nabla_{r_a} W(\Vert r_{ab} \Vert, h)
58-
+ \delta h c \sum_{b} V_b \psi_{ab} \cdot \nabla_{r_a} W(\Vert r_{ab} \Vert, h),
57+
\frac{\mathrm{d}\rho_a}{\mathrm{d}t} = \sum_{b} m_b v_{ab} \cdot \nabla W_{ab}
58+
+ \delta h c \sum_{b} V_b \psi_{ab} \cdot \nabla W_{ab},
5959
```
6060
where ``V_b = m_b / \rho_b`` is the volume of particle ``b`` and ``\psi_{ab}`` depends on
6161
the density diffusion method (see [`DensityDiffusion`](@ref) for available terms).
@@ -109,3 +109,88 @@ term is very expensive and adds about 40--50% of computational cost.
109109
Modules = [TrixiParticles]
110110
Pages = [joinpath("schemes", "fluid", "weakly_compressible_sph", "density_diffusion.jl")]
111111
```
112+
113+
## [Particle Shifting Technique](@id shifting)
114+
115+
The Particle Shifting Technique (PST) is used to correct tensile instability
116+
in regions of low pressure, as observed in viscous flow around an object.
117+
Without PST, tensile instability causes non-physical separation of the fluid
118+
from the object, introducing void regions behind the object.
119+
120+
At lower resolutions, PST alone can be effective to correct a viscous flow
121+
around a cylinder, as shown in this figure.
122+
![particle_shifting](https://github.com/user-attachments/assets/70892b0b-af36-4531-b328-f73e63a5e33c)
123+
At higher resolutions, PST alone is not effective anymore; see the figure in
124+
[Tensile Instability Control](@ref tic).
125+
We recommend using PST and Tensile Instability Control together
126+
in such simulations.
127+
128+
### Mathematical formulation
129+
130+
We use the following formulation by [Sun et al. (2018)](@cite Sun2018).
131+
After each time step, a correction term ``\delta r_a`` is added to the position ``r_a``
132+
of particle ``a``, which is given by
133+
```math
134+
\delta r_a = -4 \Delta t \, v_\text{max} h
135+
\sum_b \left( 1 + R \left( \frac{W_{ab}}{W(\Delta x_a)} \right)^n \right) \nabla W_{ab}
136+
\frac{m_b}{\rho_a + \rho_b},
137+
```
138+
where:
139+
- ``\Delta t`` is the time step,
140+
- ``v_\text{max}`` is the maximum velocity over all particles,
141+
- ``h`` is the smoothing length,
142+
- ``R`` and ``n`` are constants, which are set to ``0.2`` and ``4`` respectively,
143+
- ``W(\Delta x_a)`` is the smoothing kernel of the particle size of particle ``a``,
144+
which can be interpreted as the target particle spacing that we want to achieve.
145+
- ``\nabla W_{ab}`` is the gradient of the smoothing kernel,
146+
- ``m_b`` is the mass of particle ``b``,
147+
- ``\rho_a, \rho_b`` is the density of particles ``a`` and ``b``, respectively.
148+
149+
Note that we replaced ``\text{CFL} \cdot \text{Ma}`` by ``\Delta t \cdot v_\text{max} / h``,
150+
as explained in [Sun2018](@cite Sun2018) on page 29, right above Equation 9.
151+
152+
The ``\delta``-SPH method (WCSPH with density diffusion) together with this formulation
153+
of PST is commonly referred to as ``\delta^+``-SPH.
154+
155+
The Particle Shifting Technique can be applied in form
156+
of the [`ParticleShiftingCallback`](@ref).
157+
158+
## [Tensile Instability Control](@id tic)
159+
160+
Tensile Instability Control (TIC) is a pressure acceleration formulation to correct tensile
161+
instability in regions of low pressure, as observed in viscous flow around an object.
162+
The technique was introduced by [Sun et al. (2018)](@cite Sun2018).
163+
The formulation is described in Section 2.1 of this paper.
164+
It can be used in combination with the [Particle Shifting Technique (PST)](@ref shifting)
165+
to effectively prevent non-physical separation of the fluid from the object.
166+
167+
As can be seen in the following figure, TIC alone can cause instabilities
168+
and does not improve the simulation.
169+
PST alone can mostly prevent separation at lower resolutions.
170+
A small void region is still visible, but quickly disappears.
171+
The combination of PST and TIC prevents separation effectively.
172+
![low_res](https://github.com/user-attachments/assets/5b30d440-8ca5-4c13-94d0-d110de2eb7cc)
173+
174+
At higher resolutions, PST alone is not effective to prevent separation, as can be seen
175+
in the next figure.
176+
Only the combination of PST and TIC is able to produce physical results.
177+
![high_res](https://github.com/user-attachments/assets/674aec76-33e6-4ee3-bcd7-ba8c381a2775)
178+
179+
### Mathematical formulation
180+
181+
The force that particle ``a`` experiences from particle ``b`` due to pressure is given by
182+
```math
183+
f_{ab} = -m_a m_b \frac{p_a + p_b}{\rho_a \rho_b} \nabla W_{ab}
184+
```
185+
for the WCSPH method with [`ContinuityDensity`](@ref).
186+
187+
The TIC formulation changes this force to
188+
```math
189+
f_{ab} = -m_a m_b \frac{|p_a| + p_b}{\rho_a \rho_b} \nabla W_{ab}.
190+
```
191+
Note that this formulation is asymmetric and sacrifices conservation of linear and angular
192+
momentum.
193+
194+
```@docs
195+
tensile_instability_control
196+
```

examples/fluid/dam_break_oil_film_2d.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ oil_viscosity = ViscosityMorris(nu=nu_sim_oil)
2929

3030
# TODO: broken if both systems use surface tension
3131
trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"),
32-
sol=nothing, fluid_particle_spacing=fluid_particle_spacing,
32+
sol=nothing, fluid_particle_spacing=fluid_particle_spacing, tspan=tspan,
3333
viscosity=ViscosityMorris(nu=nu_sim_water), smoothing_length=smoothing_length,
3434
gravity=gravity, density_diffusion=nothing, sound_speed=sound_speed,
3535
prefix="", reference_particle_spacing=fluid_particle_spacing)

examples/fluid/periodic_channel_2d.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ smoothing_kernel = SchoenbergCubicSplineKernel{2}()
3535
fluid_density_calculator = ContinuityDensity()
3636
viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0)
3737

38+
# `pressure_acceleration=nothing` is the default and can be overwritten with `trixi_include`
3839
fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator,
3940
state_equation, smoothing_kernel,
40-
smoothing_length, viscosity=viscosity)
41+
smoothing_length, viscosity=viscosity,
42+
pressure_acceleration=nothing)
4143

4244
# ==========================================================================================
4345
# ==== Boundary
@@ -65,8 +67,10 @@ ode = semidiscretize(semi, tspan)
6567

6668
info_callback = InfoCallback(interval=100)
6769
saving_callback = SolutionSavingCallback(dt=0.02, prefix="")
70+
# This can be overwritten with `trixi_include`
71+
extra_callback = nothing
6872

69-
callbacks = CallbackSet(info_callback, saving_callback)
73+
callbacks = CallbackSet(info_callback, saving_callback, extra_callback)
7074

7175
# Use a Runge-Kutta method with automatic (error based) time step size control.
7276
# Limiting of the maximum stepsize is necessary to prevent crashing.

0 commit comments

Comments
 (0)