Skip to content

Commit 22d263a

Browse files
authored
Merge branch 'main' into oriented-bbox
2 parents 930aa3c + 7f6ec8a commit 22d263a

File tree

22 files changed

+894
-46
lines changed

22 files changed

+894
-46
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,20 @@ jobs:
8080
with:
8181
annotate: true
8282
# Only run coverage in one Job (Ubuntu and latest Julia version)
83-
coverage: ${{ matrix.os == 'ubuntu-latest' && matrix.version == '1' }}
83+
coverage: ${{ matrix.os == 'ubuntu-latest' && matrix.version == '1.11' }}
8484
env:
8585
TRIXIPARTICLES_TEST: unit
8686

87-
- name: Process coverage results
87+
- name: Process unit coverage results
8888
# Only run coverage in one Job (Ubuntu and latest Julia version)
89-
if: matrix.os == 'ubuntu-latest' && matrix.version == '1'
89+
if: matrix.os == 'ubuntu-latest' && matrix.version == '1.11'
9090
uses: julia-actions/julia-processcoverage@v1
9191
with:
9292
directories: src,test
9393

94-
- name: Upload coverage report to Codecov
94+
- name: Upload unit coverage report to Codecov
9595
# Only run coverage in one Job (Ubuntu and latest Julia version)
96-
if: matrix.os == 'ubuntu-latest' && matrix.version == '1'
96+
if: matrix.os == 'ubuntu-latest' && matrix.version == '1.11'
9797
uses: codecov/codecov-action@v5
9898
with:
9999
files: lcov.info
@@ -106,6 +106,25 @@ jobs:
106106
uses: julia-actions/julia-runtest@v1
107107
with:
108108
annotate: true
109-
coverage: false
109+
# Only run coverage in one Job (Ubuntu and latest Julia version)
110+
coverage: ${{ matrix.os == 'ubuntu-latest' && matrix.version == '1.11' }}
110111
env:
111112
TRIXIPARTICLES_TEST: examples
113+
114+
- name: Process total coverage results
115+
# Only run coverage in one Job (Ubuntu and latest Julia version)
116+
if: matrix.os == 'ubuntu-latest' && matrix.version == '1.11'
117+
uses: julia-actions/julia-processcoverage@v1
118+
with:
119+
directories: src,test
120+
121+
- name: Upload total coverage report to Codecov
122+
# Only run coverage in one Job (Ubuntu and latest Julia version)
123+
if: matrix.os == 'ubuntu-latest' && matrix.version == '1.11'
124+
uses: codecov/codecov-action@v5
125+
with:
126+
files: lcov.info
127+
fail_ci_if_error: true
128+
flags: total
129+
env:
130+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

NEWS.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,29 @@ used in the Julia ecosystem. Notable changes will be documented in this file for
66

77
## Version 0.4.2
88

9+
### API Changes
10+
11+
- Keyword argument `n_clamped_particles` of the `TotalLagrangianSPHSystem`
12+
has been deprecated in favor of a new kwarg `clamped_particles`.
13+
914
### Features
1015

1116
- Added `OscillatingMotion2D` to create an oscillating `PrescribedMotion` combining
1217
translation and rotation (#915).
18+
- Added `BoundaryModelDynamicalPressureZhang` for `OpenBoundarySystem` (#900).
19+
- Added `PrescribedMotion` to clamped particles in `TotalLagrangianSPHSystem` (#896).
20+
- Added new boundary density calculator `PressureBoundaries` specifically for
21+
`ImplicitIncompressibleSPHSystem` (#946).
22+
- Included wall velocity in interpolation (#941).
23+
- 2D dam break validation now compares against the results from De Courcy et al. (#934).
24+
- Improved performance of `TotalLagrangianSPHSystem` on GPUs (#968).
25+
26+
### Important Bugfixes
27+
28+
- Fixed transport velocity formulation with tensile instability control (#948).
29+
- Fixed `TotalLagrangianSPHSystem` close to open boundaries (#954).
30+
- `extrude_geometry` now doesn't adjust the particle spacing (#965).
31+
- Reduced overhead of `UpdateCallback` when no update operations are performed (#973).
1332

1433
## Version 0.4.1
1534

Project.toml

Lines changed: 3 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 <44124897+efaulhaber@users.noreply.github.com>"]
4-
version = "0.4.2-dev"
4+
version = "0.4.2"
55

66
[deps]
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
@@ -34,6 +34,7 @@ TrixiBase = "9a0f1c46-06d5-4909-a5a3-ce25d3fa3284"
3434
WriteVTK = "64499a7a-5c06-52f2-abe2-ccb03c286192"
3535

3636
[weakdeps]
37+
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
3738
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
3839
OrdinaryDiffEqCore = "bbf590c4-e513-4bbe-9b18-05decba2e5d8"
3940

@@ -50,6 +51,7 @@ FastPow = "0.1"
5051
FileIO = "1"
5152
ForwardDiff = "1"
5253
GPUArraysCore = "0.2"
54+
IntervalSets = "0.7 - 0.7.11"
5355
JSON = "1"
5456
KernelAbstractions = "0.9"
5557
MuladdMacro = "0.2"

docs/src/preprocessing/preprocessing.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,11 @@ Pages = [joinpath("preprocessing", "point_in_poly", "winding_number_jacobson.jl"
252252
```
253253
# [Read geometries from file](@id read_geometries_from_file)
254254
Geometries can be imported using the [`load_geometry`](@ref) function.
255-
- For 3D geometries, we support the binary (`.stl`) format.
255+
- For 3D geometries, we support the binary and ASCII (`.stl`) format.
256256
- For 2D geometries, the recommended format is DXF (`.dxf`), with optional support for a simple ASCII (`.asc`) format.
257257

258+
For 3D geometries, a convenience function [`extrude_geometry`](@ref) is provided to create a 3D triangulated surface by extruding a planar mesh.
259+
258260
## ASCII Format (.asc)
259261
An .asc file contains a list of 2D coordinates, space-delimited, one point per line,
260262
where the first column are the x values and the second the y values.
@@ -301,6 +303,12 @@ Modules = [TrixiParticles]
301303
Pages = [joinpath("preprocessing", "geometries", "io.jl")]
302304
```
303305

306+
```@autodocs
307+
Modules = [TrixiParticles]
308+
Pages = [joinpath("preprocessing", "geometries", "triangle_mesh.jl")]
309+
```
310+
311+
304312
# [Particle Packing](@id particle_packing)
305313
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) following the steps introduced in [Neher2026](@cite).
306314
For a hands-on tutorial with complete examples, see the particle packing tutorial.

docs/src/refs.bib

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,15 @@ @Article{Ganzenmueller2015
330330
publisher = {Elsevier {BV}},
331331
}
332332

333+
@Book{Gasser2021,
334+
author = {Gasser, T. Christian},
335+
title = {Vascular Biomechanics: Concepts, Models, and Applications},
336+
year = {2021},
337+
isbn = {9783030709662},
338+
doi = {10.1007/978-3-030-70966-2},
339+
publisher = {Springer International Publishing},
340+
}
341+
333342
@Article{Giles1990,
334343
author = {Giles, Michael B.},
335344
title = {Nonreflecting boundary conditions for {Euler} equation calculations},
@@ -828,6 +837,20 @@ @Article{Wendland1995
828837
publisher = {Springer Science and Business Media LLC},
829838
}
830839

840+
@Article{Westerhof2008,
841+
author = {Westerhof, Nico and Lankhaar, Jan-Willem and Westerhof, Berend E.},
842+
journal = {Medical \& Biological Engineering \& Computing},
843+
title = {The arterial Windkessel},
844+
year = {2008},
845+
issn = {1741-0444},
846+
month = {jun},
847+
number = {2},
848+
pages = {131--141},
849+
volume = {47},
850+
doi = {10.1007/s11517-008-0359-2},
851+
publisher = {Springer Science and Business Media LLC},
852+
}
853+
831854
@Article{Zhang2025,
832855
author = {Zhang, Shuoguo and Fan, Yu and Wu, Dong and Zhang, Chi and Hu, Xiangyu},
833856
journal = {Physics of Fluids},

docs/src/systems/boundary.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,9 @@ without the need to specifically identify those near the free surface.
342342
To further handle incomplete kernel support, for example in the viscous term of the momentum equation,
343343
the updated velocity of particles within the [`BoundaryZone`](@ref) is projected onto the face normal,
344344
so that only the component in flow direction is kept.
345+
346+
# Pressure Models
347+
```@autodocs
348+
Modules = [TrixiParticles]
349+
Pages = [joinpath("schemes", "boundary", "open_boundary", "pressure_model.jl")]
350+
```

docs/src/tutorials_template/tut_setup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ boundary_system = WallBoundarySystem(tank.boundary, boundary_model)
165165
nothing # hide
166166
```
167167

168-
## Semidiscretization
168+
## [Semidiscretization](@id tut_setup_semi)
169169

170170
The key component of every simulation is the [`Semidiscretization`](@ref),
171171
which couples all systems of the simulation.

src/TrixiParticles.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export BoundaryModelMonaghanKajtar, BoundaryModelDummyParticles, AdamiPressureEx
9090
export FirstOrderMirroring, ZerothOrderMirroring, SimpleMirroring
9191
export HertzContactModel, LinearContactModel
9292
export PrescribedMotion, OscillatingMotion2D
93+
export RCRWindkesselModel
9394
export examples_dir, validation_dir
9495
export trixi2vtk, vtk2trixi
9596
export RectangularTank, RectangularShape, SphereShape, ComplexShape

src/general/gpu.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Adapt.@adapt_structure TotalLagrangianSPHSystem
2020
Adapt.@adapt_structure BoundaryZone
2121
Adapt.@adapt_structure SystemBuffer
2222
Adapt.@adapt_structure OpenBoundarySystem
23+
Adapt.@adapt_structure RCRWindkesselModel
2324

2425
KernelAbstractions.get_backend(::PtrArray) = KernelAbstractions.CPU()
2526
function KernelAbstractions.get_backend(system::AbstractSystem)

src/preprocessing/geometries/io.jl

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ Supported file formats are `.stl`, `.asc` and `dxf`.
66
For comprehensive information about the supported file formats, refer to the documentation at
77
[Read geometries from file](@ref read_geometries_from_file).
88
9+
!!! note
10+
ASCII STL files may contain multiple `solid ... endsolid` patches. In that case
11+
the function returns a `Vector{TriangleMesh}` with one `TriangleMesh` per patch.
12+
For single-patch files the function returns a single `TriangleMesh`.
13+
If you prefer a single combined geometry instead of multiple patches, call
14+
`union(geometries...)` on the returned vector to merge all patches into one `TriangleMesh`.
15+
916
# Arguments
1017
- `filename`: Name of the file to be loaded.
1118
@@ -132,7 +139,8 @@ end
132139

133140
# FileIO.jl docs:
134141
# https://juliaio.github.io/FileIO.jl/stable/implementing/#All-at-once-I/O:-implementing-load-and-save
135-
function load(fn::FileIO.File{FileIO.format"STL_BINARY"}; element_types...)
142+
function load(fn::Union{FileIO.File{FileIO.format"STL_BINARY"},
143+
FileIO.File{FileIO.format"STL_ASCII"}}; element_types...)
136144
open(fn) do s
137145
FileIO.skipmagic(s) # skip over the magic bytes
138146
load(s; element_types...)
@@ -155,6 +163,81 @@ function load(fs::FileIO.Stream{FileIO.format"STL_BINARY"}; ELTYPE=Float64)
155163
return TriangleMesh(face_vertices, normals, vertices)
156164
end
157165

166+
function load(fs::FileIO.Stream{FileIO.format"STL_ASCII"}; ELTYPE=Float64)
167+
# ASCII STL (solid ... endsolid)
168+
io = FileIO.stream(fs)
169+
170+
# Unlike the binary STL format, the ASCII STL does not include a face count up front;
171+
# faces must be discovered by parsing until the end of the file.
172+
face_vertices = Tuple{SVector{3, ELTYPE}, SVector{3, ELTYPE}, SVector{3, ELTYPE}}[]
173+
vertices = SVector{3, ELTYPE}[]
174+
normals = SVector{3, ELTYPE}[]
175+
# ASCII STL files may contain multiple "solid ... endsolid" patches.
176+
# Collect each patch as a separate `TriangleMesh` and return a Vector.
177+
# If the file contains only one patch we return the single `TriangleMesh`.
178+
geometries = TriangleMesh[]
179+
180+
load_data_ascii!(geometries, face_vertices, vertices, normals, io)
181+
182+
length(geometries) == 1 && return first(geometries)
183+
184+
return geometries
185+
end
186+
187+
function load_data_ascii!(geometries,
188+
face_vertices::Vector{Tuple{SVector{3, T}, SVector{3, T},
189+
SVector{3, T}}},
190+
vertices, normals, io) where {T}
191+
while !eof(io)
192+
line = strip(readline(io))
193+
low = lowercase(line)
194+
195+
if startswith(low, "endsolid")
196+
# First patch finished
197+
push!(geometries,
198+
TriangleMesh(copy(face_vertices), copy(normals), copy(vertices)))
199+
200+
empty!(face_vertices)
201+
empty!(normals)
202+
empty!(vertices)
203+
end
204+
205+
# look for facet normal ...
206+
if startswith(low, "facet")
207+
parts = split(line)
208+
# Expect: `["facet", "normal", nx, ny, nz]`
209+
@assert length(parts)>=5 "Unexpected facet normal line: $line"
210+
n = SVector{3, T}(parse(T, parts[3]), parse(T, parts[4]), parse(T, parts[5]))
211+
push!(normals, n)
212+
213+
# Consume "outer loop"
214+
while !eof(io)
215+
lowercase(strip(readline(io))) == "outer loop" && break
216+
end
217+
218+
# Read three vertex lines
219+
for _ in 1:3
220+
l = strip(readline(io))
221+
partv = split(l)
222+
@assert lowercase(partv[1])=="vertex" "Unexpected vertex line: $l"
223+
vertex = SVector{3, T}(parse(T, partv[2]), parse(T, partv[3]),
224+
parse(T, partv[4]))
225+
226+
push!(vertices, vertex)
227+
end
228+
229+
push!(face_vertices, (vertices[end - 2], vertices[end - 1], vertices[end]))
230+
231+
# Consume "endloop" and "endfacet"
232+
while !eof(io)
233+
lowercase(strip(readline(io))) == "endfacet" && break
234+
end
235+
end
236+
end
237+
238+
return geometries
239+
end
240+
158241
function load_data!(face_vertices::Vector{Tuple{SVector{3, T}, SVector{3, T},
159242
SVector{3, T}}},
160243
vertices, normals, io) where {T}

0 commit comments

Comments
 (0)