12#include "gadgetconfig.h"
23#include "../data/allvars.h"
24#include "../data/dtypes.h"
25#include "../data/intposconvert.h"
26#include "../data/mymalloc.h"
27#include "../domain/domain.h"
28#include "../fof/fof.h"
29#include "../gravtree/gravtree.h"
30#include "../logs/timer.h"
31#include "../main/simulation.h"
32#include "../mpi_utils/generic_comm.h"
33#include "../mpi_utils/mpi_utils.h"
34#include "../subfind/subfind.h"
35#include "../system/system.h"
59template <
typename T_tree,
typename T_domain,
typename T_partset>
60class sngb_comm :
public generic_comm<sngb_in, sngb_out, T_tree, T_domain, T_partset>
70 sngb_comm(T_domain *dptr, T_tree *tptr, T_partset *pptr) : gcomm(dptr, tptr, pptr) {}
75 in->IntPos[0] = Tp->P[i].IntPos[0];
76 in->IntPos[1] = Tp->P[i].IntPos[1];
77 in->IntPos[2] = Tp->P[i].IntPos[2];
79 in->Hsml = Tp->PS[i].v.DM_Hsml;
80 in->ID = Tp->P[i].ID.get();
81 in->Density = Tp->PS[i].u.s.u.DM_Density;
82 in->Count = Tp->PS[i].nearest.count;
83 for(
int k = 0; k < Tp->PS[i].nearest.count; k++)
85 in->Dist[k] = Tp->R2Loc[i].dist[k];
86 in->Index[k] = Tp->PS[i].nearest.index[k];
91 void out2particle(sngb_out *out,
int i,
int mode)
override
95 Tp->PS[i].nearest.count = out->Count;
97 for(
int k = 0; k < out->Count; k++)
99 Tp->R2Loc[i].dist[k] = out->Dist[k];
100 Tp->PS[i].nearest.index[k] = out->Index[k];
105 for(
int k = 0; k < out->Count; k++)
107 if(Tp->PS[i].nearest.count >= 1)
108 if(Tp->PS[i].nearest.index[0] == out->Index[k])
111 if(Tp->PS[i].nearest.count == 2)
112 if(Tp->PS[i].nearest.index[1] == out->Index[k])
117 if(Tp->PS[i].nearest.count < 2)
119 l = Tp->PS[i].nearest.count;
120 Tp->PS[i].nearest.count++;
124 l = (Tp->R2Loc[i].dist[0] > Tp->R2Loc[i].dist[1]) ? 0 : 1;
126 if(out->Dist[k] >= Tp->R2Loc[i].dist[l])
130 Tp->R2Loc[i].dist[l] = out->Dist[k];
131 Tp->PS[i].nearest.index[l] = out->Index[k];
133 if(Tp->PS[i].nearest.count == 2)
134 if(Tp->PS[i].nearest.index[0] == Tp->PS[i].nearest.index[1])
135 Terminate(
"this is not supposed to happen");
143 int evaluate(
int target,
int mode,
int thread_id,
int action, sngb_in *in,
int numnodes,
node_info *firstnode,
144 sngb_out &out)
override
148 double density = in->Density;
149 double hsml = in->Hsml;
150 int count = in->Count;
154 for(
int k = 0; k < count; k++)
156 dist[k] = in->Dist[k];
157 index[k] = in->Index[k];
161 if(index[0] == index[1])
163 Terminate(
"target=%d mode=%d\n", target, mode);
172 for(
int k = 0; k < numnodes; k++)
182 no = firstnode[k].
Node;
183 no = Tree->get_nodep(no)->nextnode;
186 int shmrank = Tree->TreeSharedMem_ThisTask;
190 if(no < Tree->MaxPart)
192 auto *P = Tree->get_Pp(no, shmrank);
195 no = Tree->get_nextnodep(shmrank)[no];
197 if(P->ID.get() != ID)
199 if(PS->
u.s.
u.DM_Density > density)
203 Tp->nearest_image_intpos_to_pos(P->IntPos, intpos, dxyz);
205 double h2 = hsml * hsml;
207 double r2 = dxyz[0] * dxyz[0];
211 r2 += dxyz[1] * dxyz[1];
215 r2 += dxyz[2] * dxyz[2];
221 int task = D->ThisTask + (shmrank - Tree->TreeSharedMem_ThisTask);
223 if(task < 0 || task >= D->NTask)
224 Terminate(
"illegal task=%d D->NTask=%d", task, D->NTask);
229 index[count] = {task, PS->InvIndex};
234 int k = (dist[0] > dist[1]) ? 0 : 1;
239 index[k] = {task, PS->InvIndex};
245 else if(no < Tree->MaxPart + Tree->MaxNodes)
249 if(no < Tree->FirstNonTopLevelNode)
256 gravnode *current = Tree->get_nodep(no, shmrank);
262 Tp->nearest_image_intpos_to_pos(current->
center.da, intpos,
267 double dist = hsml + lenhalf;
269 if(
fabs(dxyz[0]) > dist)
271 if(
fabs(dxyz[1]) > dist)
273 if(
fabs(dxyz[2]) > dist)
277 dist +=
FACT1 * 2.0 * lenhalf;
278 if(dxyz[0] * dxyz[0] + dxyz[1] * dxyz[1] + dxyz[2] * dxyz[2] > dist * dist)
284 else if(no >= Tree->ImportedNodeOffset)
286 Terminate(
"do not expect imported points here");
292 Tree->tree_export_node_threads(no, target, &Thread);
294 no = Tree->Nextnode[no - Tree->MaxNodes];
301 for(
int k = 0; k < count; k++)
303 out.Dist[k] = dist[k];
304 out.Index[k] = index[k];
311template <
typename partset>
312void fof<partset>::subfind_find_nearesttwo(
domain<partset> *SubDomain,
int num,
int *list)
314 subfind_collective_printf(
"SUBFIND: root-task=%d: Start finding nearest two.\n", ThisTask);
316 for(
int i = 0; i < num; i++)
317 Tp->PS[list[i]].nearest.count = 0;
324 subfind_collective_printf(
"SUBFIND: root-task=%d: Done with nearest two.\n", ThisTask);
328#include "../data/simparticles.h"
329template class fof<simparticles>;
331#if defined(LIGHTCONE) && defined(LIGHTCONE_PARTICLES_GROUPS)
332#include "../data/lcparticles.h"
333template class fof<lcparticles>;
virtual void out2particle(T_out *out, int i, int mode)=0
virtual void particle2in(T_in *in, int i)=0
virtual int evaluate(int target, int mode, int thread_id, int action, T_in *in, int numnodes, node_info *firstnode, T_out &out)=0
#define MODE_LOCAL_PARTICLES
#define BITS_FOR_POSITIONS
unsigned char nextnode_shmrank
vector< MyIntPosType > center
unsigned char sibling_shmrank