|
1 | | -# Sampling of Geometries |
| 1 | +# [Sampling of Geometries](@id sampling_of_geometries) |
2 | 2 |
|
3 | 3 | Generating the initial configuration of a simulation requires filling volumes (3D) or surfaces (2D) of complex geometries with particles. |
4 | 4 | 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") |
250 | 250 | Modules = [TrixiParticles] |
251 | 251 | Pages = [joinpath("preprocessing", "point_in_poly", "winding_number_jacobson.jl")] |
252 | 252 | ``` |
| 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. |
253 | 298 |
|
254 | 299 | ```@autodocs |
255 | 300 | Modules = [TrixiParticles] |
256 | 301 | Pages = [joinpath("preprocessing", "geometries", "io.jl")] |
257 | 302 | ``` |
258 | 303 |
|
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 | +``` |
260 | 354 |
|
261 | | -TODO |
262 | 355 |
|
263 | 356 | ```@autodocs |
264 | 357 | Modules = [TrixiParticles] |
|
0 commit comments