Skip to content

Commit ccd08be

Browse files
authored
Reopen #221: Transport Velocity for EDAC (#436)
* add average pressure * add transport velocity * add tvf in rhs * add update callback * use `step_limiter!` instead of using a callback * add taylor green vortex example * add lid driven cavity example * add periodic array of cylinder example * add tests * add Random package * reexport `seed!` * remove obsolet `system_index` * skip CI * add callback * rename edac cache * move functions to `transport_velocity.jl` * prepare for wcsph * calculate volume term on the fly * adapt example files * time dependent initial velocity function * time dependent pressure function * remove velocity function * multi dimensional functions * apply formatter * fix for open boundaries * add `UpdateCallback` * fix typo * prepare for merge `update-callback` * fix bug * fix example * fix tests * fix update bug * apply formatter * fix test * minor changes * add tests * add docs * fix tpos * add configuration check * add setter for tvf * fix callback used check * adapt examples * minor changes * clean up * add tgv validation example * add ldc validation * modify validation * increase `maxiters` * remove double velocity initialization * add random displacement * implement suggestions * update `NEWS.md` * remove check for viscosity * fix tests * add short tilde description in docs * remove discarded example from tests * implement suggestions * apply formatter * implement suggestions * add comment * fix test
1 parent 3b4d6fd commit ccd08be

File tree

23 files changed

+958
-18
lines changed

23 files changed

+958
-18
lines changed

NEWS.md

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

6+
## Version 0.2.3
7+
8+
### Highlights
9+
Transport Velocity Formulation (TVF) based on the work of Ramachandran et al. "Entropically damped artificial compressibility for SPH" (2019) was added.
10+
611
## Version 0.2.2
712

813
### Highlights

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "TrixiParticles"
22
uuid = "66699cd8-9c01-4e9d-a059-b96c86d16b3a"
33
authors = ["erik.faulhaber <[email protected]>"]
4-
version = "0.2.3-dev"
4+
version = "0.2.3"
55

66
[deps]
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
@@ -21,6 +21,7 @@ MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221"
2121
PointNeighbors = "1c4d5385-0a27-49de-8e2c-43b175c8985c"
2222
Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588"
2323
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
24+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
2425
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
2526
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
2627
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"

docs/src/refs.bib

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ @Article{Adami2012
1313
}
1414

1515

16+
@Article{Adami2013,
17+
author = {S. Adami and X.Y. Hu and N.A. Adams},
18+
journal = {Journal of Computational Physics},
19+
title = {A transport-velocity formulation for smoothed particle hydrodynamics},
20+
year = {2013},
21+
month = {may},
22+
pages = {292--307},
23+
volume = {241},
24+
doi = {10.1016/j.jcp.2013.01.043},
25+
groups = {enhancement},
26+
publisher = {Elsevier {BV}},
27+
}
28+
29+
1630
@Article{Akinci2012,
1731
author = {Akinci, Nadir and Ihmsen, Markus and Akinci, Gizem and Solenthaler, Barbara and Teschner, Matthias},
1832
journal = {ACM Transactions on Graphics},

docs/src/systems/entropically_damped_sph.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,64 @@ is a good choice for a wide range of Reynolds numbers (0.0125 to 10000).
4545
Modules = [TrixiParticles]
4646
Pages = [joinpath("schemes", "fluid", "entropically_damped_sph", "system.jl")]
4747
```
48+
49+
## [Transport Velocity Formulation (TVF)](@id transport_velocity_formulation)
50+
Standard SPH suffers from problems like tensile instability or the creation of void regions in the flow.
51+
To address these problems, [Adami (2013)](@cite Adami2013) modified the advection velocity and added an extra term to the momentum equation.
52+
The authors introduced the so-called Transport Velocity Formulation (TVF) for WCSPH. [Ramachandran (2019)](@cite Ramachandran2019) applied the TVF
53+
also for the [EDAC](@ref edac) scheme.
54+
55+
The transport velocity ``\tilde{v}_a`` of particle ``a`` is used to evolve the position of the particle ``r_a`` from one time step to the next by
56+
57+
```math
58+
\frac{\mathrm{d} r_a}{\mathrm{d}t} = \tilde{v}_a
59+
```
60+
61+
and is obtained at every time-step ``\Delta t`` from
62+
63+
```math
64+
\tilde{v}_a (t + \Delta t) = v_a (t) + \Delta t \left(\frac{\tilde{\mathrm{d}} v_a}{\mathrm{d}t} - \frac{1}{\rho_a} \nabla p_{\text{background}} \right),
65+
```
66+
67+
where ``\rho_a`` is the density of particle ``a`` and ``p_{\text{background}}`` is a constant background pressure field.
68+
The tilde in the second term of the right hand side indicates that the material derivative has an advection part.
69+
70+
The discretized form of the last term is
71+
72+
```math
73+
-\frac{1}{\rho_a} \nabla p_{\text{background}} \approx -\frac{p_{\text{background}}}{m_a} \sum_b \left(V_a^2 + V_b^2 \right) \nabla_a W_{ab},
74+
```
75+
76+
where ``V_a``, ``V_b`` denote the volume of particles ``a`` and ``b`` respectively.
77+
Note that although in the continuous case ``\nabla p_{\text{background}} = 0``, the discretization is not 0th-order consistent for **non**-uniform particle distribution,
78+
which means that there is a non-vanishing contribution only when particles are disordered.
79+
That also means that ``p_{\text{background}}`` occurs as prefactor to correct the trajectory of a particle resulting in uniform pressure distributions.
80+
Suggested is a background pressure which is in the order of the reference pressure but can be chosen arbitrarily large when the time-step criterion is adjusted.
81+
82+
The inviscid momentum equation with an additional convection term for a particle moving with ``\tilde{v}`` is
83+
84+
```math
85+
\frac{\tilde{\mathrm{d}} \left( \rho v \right)}{\mathrm{d}t} = -\nabla p + \nabla \cdot \bm{A},
86+
```
87+
88+
where the tensor ``\bm{A} = \rho v\left(\tilde{v}-v\right)^T`` is a consequence of the modified
89+
advection velocity and can be interpreted as the convection of momentum with the relative velocity ``\tilde{v}-v``.
90+
91+
The discretized form of the momentum equation for a particle ``a`` reads as
92+
93+
```math
94+
\frac{\tilde{\mathrm{d}} v_a}{\mathrm{d}t} = \frac{1}{m_a} \sum_b \left(V_a^2 + V_b^2 \right) \left[ -\tilde{p}_{ab} \nabla_a W_{ab} + \frac{1}{2} \left(\bm{A}_a + \bm{A}_b \right) \cdot \nabla_a W_{ab} \right].
95+
```
96+
97+
Here, ``\tilde{p}_{ab}`` is the density-weighted pressure
98+
99+
```math
100+
\tilde{p}_{ab} = \frac{\rho_b p_a + \rho_a p_b}{\rho_a + \rho_b},
101+
```
102+
103+
with the density ``\rho_a``, ``\rho_b`` and the pressure ``p_a``, ``p_b`` of particles ``a`` and ``b`` respectively. ``\bm{A}_a`` and ``\bm{A}_b`` are the convection tensors for particle ``a`` and ``b`` respectively and are given, e.g. for particle ``a``, as ``\bm{A}_a = \rho v_a\left(\tilde{v}_a-v_a\right)^T``.
104+
105+
```@autodocs
106+
Modules = [TrixiParticles]
107+
Pages = [joinpath("schemes", "fluid", "transport_velocity.jl")]
108+
```
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Lid-driven cavity
2+
#
3+
# S. Adami et al
4+
# "A transport-velocity formulation for smoothed particle hydrodynamics".
5+
# In: Journal of Computational Physics, Volume 241 (2013), pages 292-307.
6+
# https://doi.org/10.1016/j.jcp.2013.01.043
7+
8+
using TrixiParticles
9+
using OrdinaryDiffEq
10+
11+
# ==========================================================================================
12+
# ==== Resolution
13+
particle_spacing = 0.02
14+
15+
# Make sure that the kernel support of fluid particles at a boundary is always fully sampled
16+
boundary_layers = 4
17+
18+
# ==========================================================================================
19+
# ==== Experiment Setup
20+
tspan = (0.0, 5.0)
21+
reynolds_number = 100.0
22+
23+
cavity_size = (1.0, 1.0)
24+
25+
fluid_density = 1.0
26+
27+
const VELOCITY_LID = 1.0
28+
sound_speed = 10 * VELOCITY_LID
29+
30+
pressure = sound_speed^2 * fluid_density
31+
32+
viscosity = ViscosityAdami(; nu=VELOCITY_LID / reynolds_number)
33+
34+
cavity = RectangularTank(particle_spacing, cavity_size, cavity_size, fluid_density,
35+
n_layers=boundary_layers,
36+
faces=(true, true, true, false), pressure=pressure)
37+
38+
lid_position = 0.0 - particle_spacing * boundary_layers
39+
lid_length = cavity.n_particles_per_dimension[1] + 2boundary_layers
40+
41+
lid = RectangularShape(particle_spacing, (lid_length, 3),
42+
(lid_position, cavity_size[2]), density=fluid_density)
43+
44+
# ==========================================================================================
45+
# ==== Fluid
46+
47+
smoothing_length = 1.0 * particle_spacing
48+
smoothing_kernel = SchoenbergQuinticSplineKernel{2}()
49+
50+
fluid_system = EntropicallyDampedSPHSystem(cavity.fluid, smoothing_kernel, smoothing_length,
51+
density_calculator=ContinuityDensity(),
52+
sound_speed, viscosity=viscosity,
53+
transport_velocity=TransportVelocityAdami(pressure))
54+
55+
# ==========================================================================================
56+
# ==== Boundary
57+
58+
lid_movement_function(t) = SVector(VELOCITY_LID * t, 0.0)
59+
60+
is_moving(t) = true
61+
62+
lid_movement = BoundaryMovement(lid_movement_function, is_moving)
63+
64+
boundary_model_cavity = BoundaryModelDummyParticles(cavity.boundary.density,
65+
cavity.boundary.mass,
66+
AdamiPressureExtrapolation(),
67+
viscosity=viscosity,
68+
smoothing_kernel, smoothing_length)
69+
70+
boundary_model_lid = BoundaryModelDummyParticles(lid.density, lid.mass,
71+
AdamiPressureExtrapolation(),
72+
viscosity=viscosity,
73+
smoothing_kernel, smoothing_length)
74+
75+
boundary_system_cavity = BoundarySPHSystem(cavity.boundary, boundary_model_cavity)
76+
77+
boundary_system_lid = BoundarySPHSystem(lid, boundary_model_lid, movement=lid_movement)
78+
79+
# ==========================================================================================
80+
# ==== Simulation
81+
bnd_thickness = boundary_layers * particle_spacing
82+
periodic_box = PeriodicBox(min_corner=[-bnd_thickness, -bnd_thickness],
83+
max_corner=cavity_size .+ [bnd_thickness, bnd_thickness])
84+
85+
semi = Semidiscretization(fluid_system, boundary_system_cavity, boundary_system_lid,
86+
neighborhood_search=GridNeighborhoodSearch{2}(; periodic_box))
87+
88+
ode = semidiscretize(semi, tspan)
89+
90+
info_callback = InfoCallback(interval=100)
91+
92+
saving_callback = SolutionSavingCallback(dt=0.02)
93+
94+
pp_callback = nothing
95+
96+
callbacks = CallbackSet(info_callback, saving_callback, pp_callback, UpdateCallback())
97+
98+
# Use a Runge-Kutta method with automatic (error based) time step size control
99+
sol = solve(ode, RDPK3SpFSAL49(),
100+
abstol=1e-6, # Default abstol is 1e-6 (may needs to be tuned to prevent boundary penetration)
101+
reltol=1e-4, # Default reltol is 1e-3 (may needs to be tuned to prevent boundary penetration)
102+
dtmax=1e-2, # Limit stepsize to prevent crashing
103+
maxiters=Int(1e7),
104+
save_everystep=false, callback=callbacks);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Channel flow through periodic array of cylinders
2+
#
3+
# S. Adami et al.
4+
# "A transport-velocity formulation for smoothed particle hydrodynamics".
5+
# In: Journal of Computational Physics, Volume 241 (2013), pages 292-307.
6+
# https://doi.org/10.1016/j.jcp.2013.01.043
7+
8+
using TrixiParticles
9+
using OrdinaryDiffEq
10+
11+
# ==========================================================================================
12+
# ==== Resolution
13+
n_particles_x = 144
14+
15+
# Make sure that the kernel support of fluid particles at a boundary is always fully sampled
16+
boundary_layers = 3
17+
18+
# ==========================================================================================
19+
# ==== Experiment Setup
20+
tspan = (0.0, 5.0)
21+
22+
acceleration_x = 2.5e-4
23+
24+
# Boundary geometry and initial fluid particle positions
25+
cylinder_radius = 0.02
26+
tank_size = (6 * cylinder_radius, 4 * cylinder_radius)
27+
fluid_size = tank_size
28+
29+
fluid_density = 1000.0
30+
nu = 0.1 / fluid_density # viscosity parameter
31+
32+
# Adami uses `c = 0.1 * sqrt(acceleration_x * cylinder_radius)`` but the original setup
33+
# from M. Ellero and N. A. Adams (https://doi.org/10.1002/nme.3088) uses `c = 0.02`
34+
sound_speed = 0.02
35+
36+
pressure = sound_speed^2 * fluid_density
37+
38+
particle_spacing = tank_size[1] / n_particles_x
39+
40+
box = RectangularTank(particle_spacing, fluid_size, tank_size,
41+
fluid_density, n_layers=boundary_layers,
42+
pressure=pressure, faces=(false, false, true, true))
43+
44+
cylinder = SphereShape(particle_spacing, cylinder_radius, tank_size ./ 2,
45+
fluid_density, sphere_type=RoundSphere())
46+
47+
fluid = setdiff(box.fluid, cylinder)
48+
boundary = union(cylinder, box.boundary)
49+
50+
# ==========================================================================================
51+
# ==== Fluid
52+
smoothing_length = 1.2 * particle_spacing
53+
smoothing_kernel = SchoenbergQuarticSplineKernel{2}()
54+
fluid_system = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, smoothing_length,
55+
sound_speed, viscosity=ViscosityAdami(; nu),
56+
transport_velocity=TransportVelocityAdami(pressure),
57+
acceleration=(acceleration_x, 0.0))
58+
59+
# ==========================================================================================
60+
# ==== Boundary
61+
boundary_model = BoundaryModelDummyParticles(boundary.density, boundary.mass,
62+
AdamiPressureExtrapolation(),
63+
viscosity=ViscosityAdami(; nu),
64+
smoothing_kernel, smoothing_length)
65+
66+
boundary_system = BoundarySPHSystem(boundary, boundary_model)
67+
68+
# ==========================================================================================
69+
# ==== Simulation
70+
periodic_box = PeriodicBox(min_corner=[0.0, -tank_size[2]],
71+
max_corner=[tank_size[1], 2 * tank_size[2]])
72+
semi = Semidiscretization(fluid_system, boundary_system,
73+
neighborhood_search=GridNeighborhoodSearch{2}(; periodic_box))
74+
75+
ode = semidiscretize(semi, tspan)
76+
77+
info_callback = InfoCallback(interval=10)
78+
saving_callback = SolutionSavingCallback(dt=0.02, prefix="")
79+
80+
callbacks = CallbackSet(info_callback, saving_callback, UpdateCallback())
81+
82+
# Use a Runge-Kutta method with automatic (error based) time step size control
83+
sol = solve(ode, RDPK3SpFSAL49(),
84+
abstol=1e-8, # Default abstol is 1e-6 (may need to be tuned to prevent boundary penetration)
85+
reltol=1e-4, # Default reltol is 1e-3 (may need to be tuned to prevent boundary penetration)
86+
dtmax=1e-2, # Limit stepsize to prevent crashing
87+
save_everystep=false, callback=callbacks);

0 commit comments

Comments
 (0)