Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: use Lagrangian tesselation for smoothing N-body plotting #4306

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

cphyc
Copy link
Member

@cphyc cphyc commented Jan 18, 2023

One solution to plot smooth-looking N-body data is to approximate them as SPH particles.

This PR explores an alternative (see https:/yipihey/LagrangianPhaseSpaceSheetEasy, credits to @yipihey) using "Lagrangian tesselation".

In the initial conditions, DM particles reside on a grid, from which we can compute a tesselation made of tetrahedron only. As the simulation progresses, these tetrahedrons will be distorted. The method implemented here samples positions within each individual tetrahedron to reconstruct a smoother version of the density field.

Comparison

This is obtained for a 64^3 tiny dataset.
The cherry on the cake: this PR is actually much faster than SPH interpolation because there's no need to build the KD-tree necessary for the SPH interpolation.

Method Result
This PR ("exact") image
This PR (1 sample / tetrahedron) image
This PR (10 samples / tetrahedron) image
This PR (100 samples / tetrahedron) image
NGP interp image
SPH interp image

TODO:

  • add documentation
  • add tests
  • support cases where particles do not form a uniform grid (e.g. when plotting high-resolution DM particles).

@cphyc cphyc changed the title ENH: use tesselation for better N-body rendering ENH: use Lagrangian tesselation for smoothing N-body plottin Jan 18, 2023
@cphyc cphyc changed the title ENH: use Lagrangian tesselation for smoothing N-body plottin ENH: use Lagrangian tesselation for smoothing N-body plotting Jan 18, 2023
@neutrinoceros
Copy link
Member

Too soon for a review I guess but just wanted to say this looks amazing.

Cherry on the cake: this PR is actually much faster than SPH interpolation because there's no need to build the KD-tree necessary for the SPH interpolation.

Can you clarify what you compared ? (since the quality can be adjusted I assume increasing it has a performance cost)

@cphyc
Copy link
Member Author

cphyc commented Jan 19, 2023

Can you clarify what you compared? (since the quality can be adjusted I assume increasing it has a performance cost)

I've updated the PR description, so hopefully, that should be better. The most crucial bit is that the SPH-interpolation scales as N log(N) while this implementation scales as N (times the number of samples).

The reason there needs to be some sampling is that we need to compute the volume of the intersection of each tetrahedron with each pixel. In principle, this could be computed exactly but the lazy way is just to (randomly) sample the tetrahedron to estimate the volume.

@neutrinoceros
Copy link
Member

The reason there needs to be some sampling is that we need to compute the volume of the intersection of each tetrahedron with each pixel. In principle, this could be computed exactly but the lazy way is just to (randomly) sample the tetrahedron to estimate the volume.

Interesting. I'm guessing there should be a point (critical number of samples) at which the lazy evaluation becomes as expensive as the exact evaluation. Is there an estimate for it ? It's not critical, but if it's known it should probably be documented.

@cphyc
Copy link
Member Author

cphyc commented Jan 21, 2023

TBH I'd eventually want to use https:/devonmpowell/r3d/ to compute the intersection between voxels and tetrahedron, but that may be too optimistic.

@yipihey
Copy link
Contributor

yipihey commented Jan 21, 2023 via email

@cphyc
Copy link
Member Author

cphyc commented Jan 22, 2023

After comments from @yipihey, I went ahead and implemented an "exact" integrator.
The good thing is that it is now "exact" (see comments below) and doesn't require any fudge parameter.
The less good news is that it is fairly slow (about ~30s to project 64^3 particles on a 800x800 grid).

The resulting picture looks like this 🍿
image

It works by noticing that the projection of a uniformly-sampled tetrahedron onto the plane is a simple geometrical figure (see below). There are only two cases to treat: either the projection of the tetrahedron is a triangle or a quadrilateral.

Triangular case Quadrilateral case
image image

My implementation works as follows:

  1. Project the four vertices defining each tetrahedron onto a plane,
  2. Find the convex hull,
  3. If the hull is made of three points, the maximum density is reached at the location of the fourth point (point 2 on the left figure above).
    If the hull is a quadrilateral, split it into two triangles with the density maximum at the intersection of the two diagonals.
  4. For each triangle, iterate over pixels within its bounding box.
  5. If the pixel centre is within the triangle, linearly interpolate the projected density at this location.
  6. If no pixel was found in the triangle, add the value of the tetrahedron to the pixel closest to the centre of mass and return

At this stage, we have an estimate of the density of all the pixels with centre in the hull. Unfortunately, if we sum these values, we don't get exactly the right integral due to aliasing issues.

  1. Repeat 5-6 correcting the density so that it sums to the right value.

The method is actually fairly accurate: since the projected density is a linear function, the mean value in a pixel is exactly the value at the pixel centre, except around the edges.

@cphyc cphyc added the new feature Something fun and new! label Jan 22, 2023
@yipihey
Copy link
Contributor

yipihey commented Jan 22, 2023 via email

@chummels
Copy link
Member

This looks awesome! Excited to see this functionality. Thanks for the work on this, @cphyc !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature Something fun and new!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants