Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
1985b2f
Add StoragePolicy to PackedBVH's primitive array (SharedPtrStorage/Va…
rmrsk Jul 9, 2026
8bcfa2d
Expose StoragePolicy on TriMeshSDF/Parser::readIntoTriangleBVH; keep …
rmrsk Jul 9, 2026
a3bfe43
Restrict TreeBVH to move-only; make PackedBVH copy/move explicit; dro…
rmrsk Jul 9, 2026
2680847
Add PackedBVH direct SFC-build constructor (no TreeBVH); AABBT::getDi…
rmrsk Jul 9, 2026
316379d
Add Examples/BuildBVH: benchmark all BVH build strategies by build time
rmrsk Jul 9, 2026
aa41867
Add PackedBVH direct top-down/SAH constructor (no TreeBVH); cover it …
rmrsk Jul 9, 2026
e225b9f
Add BVH::MidpointPartitioner (sort-less spatial split); cover all 5 b…
rmrsk Jul 9, 2026
80db72f
Fix missing reserve()s in the SFC-based build call chain
rmrsk Jul 9, 2026
615d58e
Add Point<T,Meta> and PointSoAT<T,W,Meta>: unsigned-distance point pr…
rmrsk Jul 9, 2026
4ed2139
Rework Point classes into a true SoA + AoSoA-wrapper split
rmrsk Jul 9, 2026
4a38576
SIMD-dispatch PointSoAT::getDistance2()
rmrsk Jul 9, 2026
3c8362a
Add a default SIMD width for PointSoAT/PointAoSoA
rmrsk Jul 9, 2026
7e04211
Add ClosestPoint example: point-cloud nearest-neighbor over a PackedBVH
rmrsk Jul 9, 2026
e3eeb6e
Fix O(N^2) ValueStorage BVH build from a per-leaf reserve
rmrsk Jul 9, 2026
2042a90
Drop a needless sqrt from pruneTraverse's scalar fallback
rmrsk Jul 9, 2026
c3fff39
ClosestPoint: demonstrate query-stream ordering as a cache-locality l…
rmrsk Jul 10, 2026
1b2c451
ClosestPoint: finalize design -- derive K, bake in query sorting, tri…
rmrsk Jul 10, 2026
81f05db
Extract Random + SFC ordering helpers; tidy the ClosestPoint example
rmrsk Jul 10, 2026
9be6867
ClosestPoint: trim output and verify correctness via EBGEOMETRY_EXPECT
rmrsk Jul 10, 2026
a3316ce
Fix clang -Werror unused-lambda-capture in the MidpointPartitioner test
rmrsk Jul 10, 2026
c8d62ad
ClosestPoint: collapse Nearest/SearchState, rename Group, doxygen the…
rmrsk Jul 10, 2026
a6fadc4
SFC::order: take the curve as a template parameter, drop the tag argu…
rmrsk Jul 10, 2026
b2cfd66
ClosestPoint: use "closest point" terminology; make printRow a function
rmrsk Jul 10, 2026
6a58022
ClosestPoint: drop the query-point Morton sort; rename rawQueries -> …
rmrsk Jul 10, 2026
d476a0f
ClosestPoint: use size_t metadata to drop index static_casts
rmrsk Jul 10, 2026
a363950
Split ClosestPoint into ClosestPointSFC and ClosestPointPacked examples
rmrsk Jul 10, 2026
bf3fac7
ClosestPointPacked: compare all four build strategies; 100k points
rmrsk Jul 10, 2026
b104b82
Merge origin/main into particle_soa_pr3
rmrsk Jul 10, 2026
fc9d9b2
Formatting fix
rmrsk Jul 10, 2026
7c94268
Add Hilbert SFC curve; profile it in the BVH examples; rename closest…
rmrsk Jul 10, 2026
ac78d0b
PointSoA distance API: minimum/maximum/all-lane; SphereT::getDistance…
rmrsk Jul 10, 2026
3bfb9d4
Add NearestNeighborSFCPacked/TreePacked examples (all-k-NN with recip…
rmrsk Jul 10, 2026
694dadb
Cleanup on landing page
rmrsk Jul 10, 2026
f6a2a5e
Make BVH partitioners move-based to cut top-down build time
rmrsk Jul 10, 2026
38cec4f
Add ClusterSAH direct PackedBVH constructor; profile in BuildBVH
rmrsk Jul 10, 2026
8021334
Add ClusterSAH row to NearestNeighborSFCPacked for query profiling
rmrsk Jul 10, 2026
7a37c2c
Split TreeBVH list ctor into copy/move overloads to fix direct-build …
rmrsk Jul 10, 2026
bf3b9e9
Rename NearestNeighbor examples' neighbor-count parameter k -> kNN, s…
rmrsk Jul 10, 2026
37ce5dd
More points
rmrsk Jul 10, 2026
cc712a8
Add branch-carried session notes on BVH build-method conclusions
rmrsk Jul 10, 2026
b82dbfb
Hard-code W=K=4 in point-cloud examples; bump NearestNeighbor docs to…
rmrsk Jul 10, 2026
f91982f
Note: float traversal slowdown is a SoA-width effect, not precision; …
rmrsk Jul 10, 2026
63598a9
Optimize Knn::tryInsert: cheap distance reject first, drop dedup for …
rmrsk Jul 10, 2026
7172529
Note: record tryInsert optimization + profiled/rejected group-min red…
rmrsk Jul 10, 2026
ab07541
Add ThirdParty nanoflann nearest-neighbor comparison harness
rmrsk Jul 10, 2026
93e750c
nanoflann harness: add SAH-over-points and SAH-over-groups EBGeometry…
rmrsk Jul 10, 2026
56238f6
nanoflann harness: query in natural vs Hilbert (SFC) order to show th…
rmrsk Jul 10, 2026
e46c913
Add seed-from-own-leaf option to both NearestNeighbor examples
rmrsk Jul 10, 2026
3890cf0
Note: bottom-up leaf-anchored traversal prototyped and rejected (no w…
rmrsk Jul 10, 2026
28e765e
Note: leaf-size sweep -- fewer groups/leaf is worse; kNN=1 sweet spot…
rmrsk Jul 10, 2026
40d5beb
NearestNeighbor examples: make seed-from-own-leaf the default, drop r…
rmrsk Jul 10, 2026
dd18e40
Note: correct leaf-size finding -- example query optimum is ~16, not ~32
rmrsk Jul 10, 2026
518f152
nanoflann harness: profile EBGeometry with our optimizations vs vanil…
rmrsk Jul 10, 2026
4ba3eb1
Note: profile the tree-build gap -- SAH partitioning is 79%, not plum…
rmrsk Jul 10, 2026
8fd5fb8
Note: ClusterSAH maxClusterSize sweep -- knee at ~16 (lean query only)
rmrsk Jul 10, 2026
8a9d811
Add longest-axis SAH option to BinnedSAHPartitioner (~20% faster SAH …
rmrsk Jul 10, 2026
8619509
Note: study nanoflann's build -- SAH is unnecessary; the gap is index…
rmrsk Jul 10, 2026
eef2173
Note: index-based build prototype closes the build gap (76ms vs 275-3…
rmrsk Jul 10, 2026
ca95d71
Add PointCloudBVH: a fast-build, turnkey-query point-cloud BVH
rmrsk Jul 10, 2026
e3e1817
Use a lean scalar DFS for the PointCloudBVH single-nearest query
rmrsk Jul 10, 2026
643094e
Replace the point-cloud examples with two PointCloudBVH-based ones
rmrsk Jul 10, 2026
3886718
Add brute-force reference queries to PointCloudBVH
rmrsk Jul 10, 2026
0abf12b
Fix two stale doxygen comments in PointCloudBVH
rmrsk Jul 10, 2026
6eeddca
Rename PointCloudBVH width template parameter Width -> W
rmrsk Jul 10, 2026
eb85fd9
Dev prototype: uniform-grid vs PointCloudBVH nearest-neighbor benchmark
rmrsk Jul 10, 2026
f8d3837
Rename the point-cloud examples: ClosestPoint -> ClosestPointBVH, Nea…
rmrsk Jul 11, 2026
f6ab47e
Fix clang-format: strip trailing whitespace in EBGeometry_RandomImple…
rmrsk Jul 11, 2026
7b3b035
Remove the Dev/ folder and its temporary REUSE.toml block
rmrsk Jul 11, 2026
ed4da32
Trim performance-mechanism prose from the point-cloud example READMEs
rmrsk Jul 11, 2026
dd85e5c
Branch cleanup: drop NOTES/nanoflann, add PointCloud docs page, captu…
rmrsk Jul 11, 2026
ea4b2f2
Reword SIMDClasses.rst: drop the stale "three" count of SIMD sites
rmrsk Jul 11, 2026
240ce33
ThirdParty/Chombo: drop F18, rename DCEL -> MeshSDF to mirror AMReX
rmrsk Jul 11, 2026
30c9091
Fix -Wdouble-promotion in TestPointCloudBVH under clang float builds
rmrsk Jul 11, 2026
cd55b4e
Drop samplePoints from the EBGeometry::Random row in mainpage.md
rmrsk Jul 11, 2026
f2425e6
Reuse the build's leaf order in allNearestNeighbors instead of re-sor…
rmrsk Jul 11, 2026
6d9b754
Rename ThirdParty/ to Integrations/
rmrsk Jul 11, 2026
aaae519
Fix PointCloudBVH bugs from the PR review: empty cloud, seeded-DFS st…
rmrsk Jul 11, 2026
5e076b2
Formatting: blank-line conventions in PointCloudBVHImplem
rmrsk Jul 11, 2026
3119dd2
Address remaining PR-review gaps: ClusterSAH test+doc, InstantiateAll…
rmrsk Jul 11, 2026
2fac41f
PointSoA/PointAoSoA/SFC: finite-coordinate preconditions and a_-prefi…
rmrsk Jul 11, 2026
563583d
PointCloudBVH: doc-style + terminology audit, debug hooks, and exampl…
rmrsk Jul 11, 2026
570fc3d
header docs
rmrsk Jul 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

build

# AMReX build/run artifacts (any example under ThirdParty/AMReX/<name>/).
ThirdParty/AMReX/*/plt*
ThirdParty/AMReX/*/tmp_build_dir
ThirdParty/AMReX/*/Backtrace.*
# AMReX build/run artifacts (any example under Integrations/AMReX/<name>/).
Integrations/AMReX/*/plt*
Integrations/AMReX/*/tmp_build_dir
Integrations/AMReX/*/Backtrace.*

# Chombo build artifacts (any example under ThirdParty/Chombo/<name>/).
ThirdParty/Chombo/*/d/**
ThirdParty/Chombo/*/o/**
ThirdParty/Chombo/*/f/**
# Chombo build artifacts (any example under Integrations/Chombo/<name>/).
Integrations/Chombo/*/d/**
Integrations/Chombo/*/o/**
Integrations/Chombo/*/f/**

Docs/*
!Docs/.nojekyll
Expand Down
12 changes: 11 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ for embedded-boundary (EB) codes like AMReX, but is general-purpose.
Single-word orientation: `Source/` is the library (all headers, no `.cpp`), `Tests/` is the Catch2
unit-test suite (fetched via CMake `FetchContent`, not vendored), `Examples/` holds small
standalone programs with no third-party dependencies (each independently buildable — see below),
`ThirdParty/` holds illustrative (not CI-tested) examples coupling EBGeometry to third-party
`Integrations/` holds illustrative (not CI-tested) examples coupling EBGeometry to third-party
application codes (AMReX, Chombo), and `Docs/Sphinx/` + `Docs/doxygen.conf` are the two
documentation systems.

Expand Down Expand Up @@ -243,6 +243,16 @@ hooks (clang-tidy, the debug build, Sphinx) only run via this script or explicit
compilers, SIMD levels, precisions, sanitizers, both Debug and Release) that isn't practical to
reproduce byte-for-byte locally.

## Whitespace conventions clang-format does not enforce

clang-format handles indentation, brace placement, and line wrapping, but it cannot insert blank
lines to group statements, so a few readability conventions are maintained by hand:

- **A blank line both before and after every loop** (`for`/`while`), not just after it, so the loop
reads as its own block separated from the surrounding statements. Do not stack the blank line
directly against an enclosing closing brace (a loop that is the last statement in its block needs
no blank line between it and that closing brace).

## Branching, pull requests, and other spin-offs

**You are never allowed to automatically create new branches, submit pull requests, create git
Expand Down
4 changes: 3 additions & 1 deletion Docs/Sphinx/source/BVH.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ centroids; a more expensive strategy based on the Surface Area Heuristic typical
best query performance, at a higher construction cost.

Bottom-up construction is also possible, in which case one constructs the leaf nodes first, and then merges the nodes upward until one reaches a root node.
In EBGeometry, bottom-up construction is done by means of space-filling curves (e.g., Morton codes).
In EBGeometry, bottom-up construction is done by means of space-filling curves -- Morton codes,
Hilbert curves, or nested indices. The Hilbert curve has better spatial locality than Morton (its
consecutive codes are always spatially adjacent), so it tends to produce tighter leaf groupings.

.. important::

Expand Down
14 changes: 12 additions & 2 deletions Docs/Sphinx/source/Examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ dependencies. Each one can be built directly with a compiler, with GNU Make, or
(see :ref:`Chap:Building`), and every folder ships all three (a ``GNUmakefile``, a
``CMakeLists.txt``, and a plain ``main.cpp`` compilable with a single compiler invocation).

Alongside the examples with dedicated pages below, the following BVH and point-cloud examples ship in
:file:`Examples/`:

* ``BuildBVH`` -- compares the BVH construction strategies (top-down, SAH, and the Morton, Hilbert,
and Nested space-filling-curve builds) by build time.
* ``ClosestPointBVH`` -- closest-point search over a point cloud using the ``PointCloudBVH`` class
(see :ref:`Chap:ImplemPointCloud`).
* ``NearestNeighborBVH`` -- the k-nearest-neighbor graph of a point cloud via
``PointCloudBVH::allNearestNeighbors()``.

Examples that couple EBGeometry to a third-party application code's embedded-boundary grid
generation (`AMReX <https://amrex-codes.github.io/amrex/>`_, `Chombo
<https://commons.lbl.gov/display/chombo/>`_) live separately under :file:`ThirdParty/` instead,
and additionally require that platform to be installed — see :ref:`Chap:ThirdParty`.
<https://commons.lbl.gov/display/chombo/>`_) live separately under :file:`Integrations/` instead,
and additionally require that platform to be installed — see :ref:`Chap:Integrations`.

None of the EBGeometry examples produce output for visualization; they print timing
and/or correctness information to the terminal. Each example folder also ships its own
Expand Down
111 changes: 100 additions & 11 deletions Docs/Sphinx/source/ImplemBVH.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,24 @@ Top-down construction is done through the member function ``topDownSortAndPartit
takes two optional arguments: a *partitioner* and a *leaf predicate*.

The partitioner is a functor that splits a list of ``(primitive, BV)`` pairs into ``K`` new
lists whenever a leaf is subdivided. Three ready-made partitioners are provided:
lists whenever a leaf is subdivided. Four ready-made partitioners are provided:
``BVCentroidPartitioner`` (splits on bounding-volume centroids along the longest axis -- the
default), ``PrimitiveCentroidPartitioner`` (the same idea, but splits on primitive centroids
instead), and ``BinnedSAHPartitioner`` (a Surface-Area-Heuristic partitioner, used automatically
instead), ``BinnedSAHPartitioner`` (a Surface-Area-Heuristic partitioner, used automatically
when building via ``BVH::Build::SAH`` -- see below -- and typically producing the
best-performing trees at a higher construction cost). The leaf predicate takes a ``TreeBVH`` node
and decides whether it should become a leaf (i.e. not be split any further); a default is provided,
but callers are free to supply their own of either kind.
best-performing trees at a higher construction cost), and ``MidpointPartitioner`` (splits on the
midpoint of the bounding-volume centroids' extent along the longest axis, with a single
``std::partition`` pass -- no sorting and no per-plane cost evaluation, making it the fastest of
the four to build, at the cost of not adapting to the primitive distribution the way the other
three do). ``BinnedSAHPartitioner`` and ``MidpointPartitioner`` both produce ``K`` groups by
recursively splitting into two (``std::floor(K/2)`` and ``std::ceil(K/2)``) halves, exact for
power-of-two ``K``. ``BinnedSAHPartitioner`` takes an optional final template argument
``LongestAxisOnly`` (default ``false``); setting it ``true`` bins candidate planes on only the
longest centroid-bounding-box axis instead of all three, cutting roughly a third of the binning
work (measured ~20% faster SAH builds on point clouds) for a tree-quality cost that is negligible
on near-uniform inputs. The leaf predicate takes a ``TreeBVH``
node and decides whether it should become a leaf (i.e. not be split any further); a default is
provided, but callers are free to supply their own of either kind.

Bottom-up construction
________________________
Expand All @@ -101,13 +111,92 @@ To use bottom-up construction, one may use the member function template
The template argument is the space-filling curve that the user wants to apply, from namespace
``EBGeometry::SFC`` (:file:`Source/EBGeometry_SFC.hpp`, see `the doxygen API
<doxygen/html/namespaceEBGeometry_1_1SFC.html>`__).
Currently, we support Morton codes and nested indices.
For Morton curves, one would e.g. call ``bottomUpSortAndPartition<SFC::Morton>`` while for nested indices (which are not recommended) the signature is likewise ``bottomUpSortAndPartition<SFC::Nested>``.
Currently, we support Morton codes, Hilbert curves, and nested indices.
For Morton curves, one would e.g. call ``bottomUpSortAndPartition<SFC::Morton>``; the Hilbert curve
(better spatial locality than Morton, since consecutive codes are always spatially adjacent) is
``bottomUpSortAndPartition<SFC::Hilbert>``; while for nested indices (which are not recommended) the
signature is likewise ``bottomUpSortAndPartition<SFC::Nested>``.

Build times for SFC-based bottom-up construction are generally speaking faster than top-down construction, but it tends to produce worse trees such that traversal becomes slower. For the full API,
see the Doxygen reference for
`TreeBVH <doxygen/html/classEBGeometry_1_1BVH_1_1TreeBVH.html>`__.

.. _Chap:DirectSFCBuild:

Direct construction (no TreeBVH)
___________________________________

Both construction methods above build a ``TreeBVH`` first, then require a separate ``pack()``/
``packWith()`` call to obtain a ``PackedBVH``. For workloads with many small, cheaply-copyable
primitives (points, particles) built and rebuilt often, the per-node ``shared_ptr<TreeBVH>``
allocation this implies can dominate build time. ``PackedBVH`` has a constructor that skips
``TreeBVH`` entirely:

.. code-block:: cpp

BVH::PackedBVH<T, P, K> packed(std::move(primsAndBVs), targetLeafSize);

It takes primitives **by value** (``std::vector<std::pair<P, BV>>``, a sink parameter the caller
can ``std::move`` in) rather than requiring a ``shared_ptr``-wrapped list, regardless of this
``PackedBVH``'s ``StoragePolicy`` (see :ref:`Chap:PackedBVH`'s "Storage policy" section) — combined
with ``BVH::ValueStorage<P>``, this is genuinely pointer-free from input to final storage.

Internally, this constructor:

#. Sorts primitives along a space-filling curve (``SFC::Morton`` by default; pass e.g.
``SFC::Hilbert{}`` or ``SFC::Nested{}`` as an optional trailing argument to select another curve —
a constructor template's own parameters can't be explicitly named the way a regular function
template's can, so this is a stateless tag value purely to let the curve type be deduced).
#. Cuts leaves via a single linear left-to-right scan at a caller-chosen **target leaf size**,
rather than deriving a leaf count purely from primitive count and ``K`` the way
``bottomUpSortAndPartition()`` does — giving direct control over leaf occupancy.
#. Merges the resulting leaves upward in groups of ``K``, padding the leaf count up to the next
power of ``K`` (by re-using the last real leaf's node in place of any missing child, rather than
inventing an empty placeholder) whenever it isn't already one, so every interior node still has
exactly ``K`` children — no change to ``Node``'s shape or to ``traverse()``/``pruneTraverse()``.

Since this still produces an ordinary ``PackedBVH``, every existing traversal/query facility
(``traverse()``, ``pruneTraverse()``, the SIMD dispatch) works with it identically, unchanged.

``PackedBVH`` also has a second, overloaded direct constructor covering top-down (and SAH)
construction rather than the SFC-based one above:

.. code-block:: cpp

BVH::PackedBVH<T, P, K> packed(std::move(primsAndBVs)); // top-down
BVH::PackedBVH<T, P, K> packed(std::move(primsAndBVs), BVH::BinnedSAHPartitioner<T, P, AABBT<T>, K>, stopCrit); // SAH

It reuses ``TreeBVH``'s own ``Partitioner``/``LeafPredicate`` machinery unchanged (any of
``BVCentroidPartitioner``, ``BinnedSAHPartitioner``, ``PrimitiveCentroidPartitioner``, or a
caller-supplied one), so it accepts the same arguments ``topDownSortAndPartition()`` does — but
writes nodes directly into the flat node array in depth-first pre-order as the recursion unwinds,
rather than building a persistent, ``shared_ptr``-linked ``TreeBVH`` first. Since top-down
recursion visits the root before its children, this needs no relayout pass (unlike the SFC-build
constructor above, where a bottom-up merge naturally produces the root last). Each split still
shared_ptr-wraps primitives once, up front (to reuse the existing ``Partitioner``/``LeafPredicate``
signatures) and constructs one lightweight, stack-local ``TreeBVH`` per split purely to evaluate
the stop criterion and read off its primitive list — proportionate to what
``topDownSortAndPartition()`` already does at every node, and immediately discarded rather than
kept alive as part of a persistent tree. What this constructor avoids is exactly the *persistent*
``shared_ptr<TreeBVH>`` node allocation kept alive for the tree's lifetime, which the ``Examples/BuildBVH``
benchmark measures as the traditional path's dominant build-time cost.

A third direct constructor builds via **ClusterSAH**, a fast approximation of a full SAH tree:

.. code-block:: cpp

BVH::PackedBVH<T, P, K> packed(std::move(primsAndBVs), BVH::ClusterSpec{maxClusterSize});

It first groups the primitives into small, spatially-tight *clusters* (buckets of at most
``maxClusterSize`` primitives, formed by a cheap density-adaptive midpoint subdivision that stops
early), then runs binned SAH top-down over those clusters — so SAH partitions roughly
``N / maxClusterSize`` boxes instead of all ``N`` primitives. The result is near-SAH tree quality at
a fraction of the single-threaded SAH build cost, and it stays robust across uniform, surface, and
clustered primitive distributions (a fixed Cartesian grid, by contrast, overcrowds on non-uniform
data). ``BVH::ClusterSpec::maxClusterSize`` trades build time (larger → fewer, cheaper SAH units)
against query quality (larger → coarser leaves); ``Examples/BuildBVH`` benchmarks its build time
against the other strategies.

.. tip::

Higher-level entry points such as ``Parser::readIntoPackedBVH`` don't require you to
Expand Down Expand Up @@ -405,8 +494,8 @@ the Doxygen reference for

.. _Chap:MeshSDFClasses:

Mesh Signed Distance Function Classes
--------------------------------------
Mesh SDF classes
----------------

EBGeometry provides three concrete classes for evaluating signed distances to surface meshes.
They share the same sign convention (negative inside, positive outside) but differ in data layout,
Expand Down Expand Up @@ -459,8 +548,8 @@ itself.
What is actually vectorised in ``TriMeshSDF``/``PackedBVH`` is covered in
:ref:`Chap:SIMDClasses` -- see that page for the full detail rather than repeating it here.

Primitive storage: why MeshSDF and TriMeshSDF default differently
___________________________________________________________________
Primitive storage: Facets or triangles
______________________________________

Both classes' underlying ``PackedBVH`` accepts the ``StoragePolicy`` axis described above, but
they default -- and, for ``MeshSDF``, are restricted -- differently:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _Chap:ThirdParty:
.. _Chap:Integrations:

Third party
Integrations
============

.. important::
Expand All @@ -15,31 +15,31 @@ Third party
AMReX
------

The :file:`ThirdParty/AMReX/<something>` folders couple EBGeometry to
The :file:`Integrations/AMReX/<something>` folders couple EBGeometry to
`AMReX <https://amrex-codes.github.io/amrex/>`_'s embedded-boundary grid generation: an
EBGeometry signed distance function is handed to AMReX, which uses it to cut cells at the
implicit surface. AMReX must be installed separately, with the ``AMREX_HOME`` environment
variable pointing to it. Available examples:

* :file:`ThirdParty/AMReX/Shapes`
* :file:`ThirdParty/AMReX/MeshSDF`
* :file:`ThirdParty/AMReX/PackedSpheres`
* :file:`ThirdParty/AMReX/RandomCity`
* :file:`ThirdParty/AMReX/PaintEB`
* :file:`Integrations/AMReX/Shapes`
* :file:`Integrations/AMReX/MeshSDF`
* :file:`Integrations/AMReX/PackedSpheres`
* :file:`Integrations/AMReX/RandomCity`
* :file:`Integrations/AMReX/PaintEB`

See the README in each folder for exact build and run instructions.

Chombo
-------

The :file:`ThirdParty/Chombo/<something>` folders couple EBGeometry to
The :file:`Integrations/Chombo/<something>` folders couple EBGeometry to
`Chombo <https://commons.lbl.gov/display/chombo/>`_'s embedded-boundary grid generation, in the
same spirit as the AMReX examples above. Chombo must be installed separately, with the
``CHOMBO_HOME`` environment variable pointing to it. Available examples:

* :file:`ThirdParty/Chombo/Shapes`
* :file:`ThirdParty/Chombo/DCEL`
* :file:`ThirdParty/Chombo/PackedSpheres`
* :file:`ThirdParty/Chombo/RandomCity`
* :file:`Integrations/Chombo/Shapes`
* :file:`Integrations/Chombo/MeshSDF`
* :file:`Integrations/Chombo/PackedSpheres`
* :file:`Integrations/Chombo/RandomCity`

See the README in each folder for exact build and run instructions.
32 changes: 32 additions & 0 deletions Docs/Sphinx/source/PointCloud.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.. _Chap:ImplemPointCloud:

Point clouds
============

For nearest-neighbor and closest-point work over particle clouds, EBGeometry provides
``PointCloudBVH`` (:file:`Source/EBGeometry_PointCloudBVH.hpp`). It specializes the :ref:`Chap:ImplemBVH`
machinery: it is a subclass of ``BVH::PackedBVH`` with two things the general path does not offer -- a
much cheaper **index-based build**, and **turnkey query methods** that hide ``pruneTraverse()``
entirely.

It is built directly from a raw cloud -- particle positions plus a parallel array of user metadata --
by partitioning an index permutation in place with a longest-axis midpoint split and packing the
``PointAoSoA`` leaves inline (no intermediate primitive list, no ``shared_ptr``, no separate packing
pass), which is several times faster to build than a full Surface-Area-Heuristic tree and, for
near-uniform clouds, just as tight to query.

Queries return the matched particle's cloud index (and squared distance); the user metadata is
reachable through ``metadata()``. ``closestPoint`` / ``closestPoints`` answer an arbitrary external
point, while ``nearestNeighbor`` / ``nearestNeighbors`` (and the batch ``allNearestNeighbors``) answer
a particle already in the cloud and additionally seed the search bound from that particle's own leaf
-- a strictly cheaper search an external point cannot use.

Each accelerated query also has an ``O(N)`` brute-force counterpart -- ``closestPointBruteForce`` /
``closestPointsBruteForce`` / ``nearestNeighborBruteForce`` / ``nearestNeighborsBruteForce`` -- that
answers the same question by a full linear scan. These are reference implementations for testing and
debugging (verify an accelerated result against ground truth, or A/B-test a suspected tree/traversal
bug against an unaccelerated path) and are not meant for production queries.

See the `PointCloudBVH doxygen page
<doxygen/html/classEBGeometry_1_1PointCloudBVH.html>`__ for the full interface, and
``Examples/ClosestPointBVH`` / ``Examples/NearestNeighborBVH`` for worked usage.
4 changes: 2 additions & 2 deletions Docs/Sphinx/source/Quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ examples directly:

Every folder under :file:`Examples/<something>` is a pure EBGeometry example: it
has no third-party dependencies and can be compiled with the one-liner above (see
:ref:`Chap:Examples`). Folders under :file:`ThirdParty/<Platform>/<something>` couple
:ref:`Chap:Examples`). Folders under :file:`Integrations/<Platform>/<something>` couple
EBGeometry to a third-party application code (AMReX, Chombo) and additionally require that
platform to be installed -- see :ref:`Chap:ThirdParty`.
platform to be installed -- see :ref:`Chap:Integrations`.

See :ref:`Chap:ObtainingEBGeometry` for how to clone the repository (including the submodule
needed to run the bundled examples with their default mesh), and :ref:`Chap:Building` for how to
Expand Down
Loading