PHASTA / vtkpytools

Internal tools for using VTK
https://fluid.colorado.edu/wiki/index.php/VTKpytools
BSD 3-Clause "New" or "Revised" License
0 stars 1 forks source link

feat: Distance to Wall for 2D meshes #29

Open jrwrigh opened 4 years ago

jrwrigh commented 4 years ago

Add function to compute distance from "wall" to every point in the "grid". vtkDistancePolyDataFilter

See C++ tutorial on vtkExamples website

jrwrigh commented 3 years ago

Possibly also see this ParaView forum post for a Programmable Filter that may do the same thing.

See some little progress in /users/jrwrigh/papers/.../Plotting/addWallDist.py

jrwrigh commented 2 years ago

pyvista has compute_implicit_distance, which may work similarly to the above PV forum post. Though that assumes that it's more flexible than the pyvista documentation specifies (which currently says the PolyData input is a surface).

Confirmed that compute_implicit_distance uses vtkImplicitPolyDataDistance.

jrwrigh commented 2 years ago

Detailed description on vtkImplicitPolyDataDistance says it works with the explicit points on the PolyData object, so it should be agnostic to the underlying PolyData structure. https://vtk.org/doc/nightly/html/classvtkImplicitPolyDataDistance.html#details

jrwrigh commented 2 years ago

Note that vtkDistancePolyDataFilter calls vtkImplicitPolyDataDistance in a for loop at the end of the day. https://gitlab.kitware.com/vtk/vtk/-/blob/master/Filters/General/vtkDistancePolyDataFilter.cxx#L75

jrwrigh commented 2 years ago

When @prestonTee tried to use the compute_implicit_distance, but ran into the following error:

ERROR:root:No polygons to evaluate function!

This points back to this line. In order for it to calculate the signed distance, it needs to know cell normals. But to get cell normals, it needs an actual 3D cell (since VTK is implicitly always 3D). In fact, it actually filters out the vertices and edges of the input mesh (see here). Thus it can't be used with what we're trying to do. Instead, something like:

d2wall = np.zeros(grid.npoints)
d2wallpnt = np.zeros(grid.npoints)

for i in range(wall.npoints):
    d2wallpnt = np.linalg.norm(grid.points - wall.points[i,:], axis=1)
    d2wall = np.min(d2wall, d2wallpnt, axis=1)

should work fine, if being a bit more memory intensive.