Nearest Neighbour Averaging

Hello,

I have been scouring the web to determine how to average a cell based on its nearest neighbours using ParaView, however, I have not yielded any results. My goal is to take a cell of interest, cell(x,y,z), and find its nearest neighbours in 3D space. I will then extract a value of interest from each of the nearest neighbours, and use these values to compute an average for cell(x,y,z). I am wondering if anyone knows of how I can accomplish this using ParaView?

Matthew

@cory.quammen @mathiHmmm … Would running the Cell to Point filter (finding the average point between cells) and then the Point to Cell filter (finding the average cell data from all of the cell points) do what Matthew is asking for?

It’s not obvious to me that that would work. Here @Matthew wants to exclude the cell(x,y,z), but Cell to Point followed by Point to Cell would include the value at that starting cell.

Assuming nearest neighbor here means adjacent cells, for just one cell, it would be easier to:

  • select the cell of interest (Find Data panel or selection tools above the Render View)
  • change the selection mode to exclude the starting cell (Settings → Render View → Remove seed on grow selection)
  • grow the selection by one layer (+ button in the selection tools above the Render View)
  • extract the resulting selection (Filters → Alphabetical → Extract Selection)
  • average (Filters → Alphabetical → Integrate Variables)

If you want to do this for all cells in your data set, then that requires more extensive programming in a Programmable Filter.

Here is an example using the programmable filter as Cory suggested :

  • Create some dummy input with celldata
    • Source > Unstructured Cells Types
    • Filters > PointToCellData
  • Create programmable filter with the following script. We will average the “DistanceToCenter” array
import numpy as np 
input0 = inputs[0]
num = input0.GetNumberOfCells()

Array = np.zeros(num, dtype=np.float64)
ptIds = vtk.vtkIdList()
cellIds = vtk.vtkIdList()
otherCells = vtk.vtkIdList()


for i in range(num):
       input0.GetCellPoints(i,ptIds)
       # Get all cells attached to the first point
       input0.GetPointCells(ptIds.GetId(0),cellIds)
       # similarly for all other points
       for j in range(1,ptIds.GetNumberOfIds()):
           input0.GetPointCells(ptIds.GetId(j),otherCells)
           # merge results
           for k in range(otherCells.GetNumberOfIds()):
               cellIds.InsertUniqueId(otherCells.GetId(k))
       # remove current cell
       cellIds.DeleteId(i)
       # average results
       for k in range(cellIds.GetNumberOfIds()):
           Array[i] += input0.CellData["DistanceToCenter"][cellIds.GetId(k)]
       Array[i] /= cellIds.GetNumberOfIds()

         

output.CellData.append(Array, "A")

Hello @cory.quammen and @Christos_Tsolakis,

I appreciate all of your help! I implemented both of your suggestions and I was able to get the exact result that I desired.

1 Like