Finding the 32 Nearest Gas Particles

29 views
Skip to first unread message

Nolan McPhaul

unread,
Jun 23, 2023, 4:26:20 PM6/23/23
to pynbody-users
Hello all,

I am wanting to use pynbody to go through each DM particle in a halo and find the nearest 32 gas particles to use sph to get the weighted average of gas density, temperature, and other properties, weighting it by the gas particle's distance from the DM particle. Reading through the pynbody files, it seems like this is totally accomplishable especially when reading people's posts such as "Using Pynbody KDTree"#PR601, and other similar posts. 

However, when I am calling functions such as sph.rho(), kdtree.all_nn(), sph.smooth(), and others I cannot get it to only search for the nearest 32 gas particles at each dark matter particle's position, but rather it simply searches for the nearest 32 particles to each dm particle (which most of the time is exclusively dm particles from how many there are). I've thought about playing with families to essentially create a dummy family with the dm particle's position and then essentially get rid of the dark matter particles entirely (just to try and filter them out of the search), but have been unsuccessful in this.

Also a lot of the time when I'm playing with functions such as pynbody.sph.kdmain.nn_next() it gives a segmentation fault error.

Further when playing with sph.smooth() and kdtree.all_nn() it will give me a smoothing length (which I am assuming is the radius containing the 32 nearest particles). However, when I create a filtering sphere of that smoothing radius at the same particle it contains far fewer than 32 particles and the spheres don't all contain the same number of particles. kdtree.all_nn() displays the smoothing length and then gives the distance to the n nearest particles, but most of the distances are above the smoothing length. Further when I created a sphere over the max distance listed in kdtree.all_nn() for a particle, the sphere contained more particles than the n nearest neighbors it was told to find. Any advice on what this smoothing number actually is would be helpful as well as general information about the array given by kdtree.all_nn().

If anyone has any advice or suggestions on how to best find the nearest 32 gas neighbors, it would be greatly appreciated.

Thank you very much,
Nolan McPhaul

Nolan McPhaul

unread,
Jun 27, 2023, 5:16:52 PM6/27/23
to pynbody-users
Hi,

Just to give an update, I have figured out the issues regarding the smoothing length and functions such as kdtree.nn_all() and how to get the smoothing array of the nearest n particles. However, I have still not been able to get pynbody to search only for gas particles.

My current thought is to pass a family array, indicating which particles are and are not gas, to kdmain.kdinit() to add the family pointer to all of the particle objects in smx (I think I'm understanding that correctly). I'm then wanting to add an if statement inside one of the .cpp file methods (since this appears to be where the neighbors are actually located) to only count a found particle as one of the n neighbors if it is a gas particle. My main issue is I do not know which method to add this to, because I keep going further and further into methods calling other methods and can't tell exactly where pynbody finds the nearest neighbor. I would like to add this to nn_next(), for example in the following loop:
         for (i=0; i < nCnt; i++)
        {
        pj = smx->pList[i];
        PyList_SetItem(nnList, i, PyLong_FromLong(smx->kd->p[pj].iOrder));
        PyList_SetItem(nnDist, i, PyFloat_FromDouble(smx->fList[i]));
        }
As this for loop adds the found particle to the neighbor array. However, I don't know if I need to go into one of the deeper methods such as smDomainDecomposition, smSmoothInitStep, smInitPriorityQueue, SETSMOOTH (which I can't even find the definition for) or some other method which actually finds the neighbor.

Any help on how (and where) to add this feature of searching only for gas particles would be great since I'm not used to working with C++. 

Thanks,
Nolan McPhaul

Andrew Pontzen

unread,
Jun 27, 2023, 5:58:55 PM6/27/23
to Nolan McPhaul, pynbody-users
Hi Nolan

I’m afraid I have my hands very full with other projects at the moment and can’t offer detailed guidance. What you are trying to do is far from trivial to accomplish, but I think you are on the right track. There is a quick way and a right way. The quick way would be simply to keep the inner kdtree code almost untouched, ask for far more smoothing neighbours than you need, then do some post-processing to weed out the ones you don’t want (i.e. the ones from the wrong family). 

The right way would be to go deep into the code, but there will be a lot of loops that need to be changed I’m afraid. The KDtree is old code, ultimately derived from PKDgrav, that wasn’t really written with ‘flexibility’ in mind.

Hope this is of some help - sorry not to be able to offer more right now.

All the best

Andrew


--
You received this message because you are subscribed to the Google Groups "pynbody-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pynbody-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pynbody-users/258da9e1-f029-430e-a5c2-763e7d67e04fn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages