12#include "gadgetconfig.h"
22#include "../data/allvars.h"
23#include "../data/dtypes.h"
24#include "../data/intposconvert.h"
25#include "../data/mymalloc.h"
26#include "../domain/domain.h"
27#include "../fof/fof.h"
28#include "../logs/timer.h"
29#include "../main/simulation.h"
30#include "../mpi_utils/generic_comm.h"
31#include "../ngbtree/ngbtree.h"
32#include "../system/system.h"
53template <
typename T_tree,
typename T_domain,
typename T_partset>
54class fofdata_comm :
public generic_comm<fofdata_in, fofdata_out, T_tree, T_domain, T_partset>
64 fofdata_comm(T_domain *dptr, T_tree *tptr, T_partset *pptr)
65 :
generic_comm<fofdata_in, fofdata_out, T_tree, T_domain, T_partset>(dptr, tptr, pptr)
72 for(
int k = 0; k < 3; k++)
73 in->IntPos[k] = Tp->P[i].IntPos[k];
75 in->Hsml = Tp->fof_nearest_hsml[i];
81 if(out->Distance < Tp->fof_nearest_distance[i])
83 Tp->fof_nearest_distance[i] = out->Distance;
84 Tp->MinID[i] = out->MinID;
85 Tp->MinIDTask[i] = out->MinIDTask;
87 Tp->PS[i].v.DM_Hsml = out->DM_Hsml;
92 int evaluate(
int target,
int mode,
int thread_id,
int action, fofdata_in *in,
int numnodes,
node_info *firstnode, fofdata_out &out)
101 for(
int k = 0; k < numnodes; k++)
111 no = firstnode[k].
Node;
112 no = Tree->get_nodep(no)->nextnode;
115 int shmrank = Tree->TreeSharedMem_ThisTask;
119 if(no < Tree->MaxPart)
122 auto P = Tree->get_Pp(no, shmrank);
124 no = Tree->get_nextnodep(shmrank)[no];
126 if(shmrank != Tree->TreeSharedMem_ThisTask)
127 Terminate(
"this routine may not consider shared memory particles");
130 Tp->nearest_image_intpos_to_pos(P->IntPos, intpos, dxyz);
134 if(
fabs(dxyz[0]) > dist)
136 if(
fabs(dxyz[1]) > dist)
138 if(
fabs(dxyz[2]) > dist)
141 double r2 = dxyz[0] * dxyz[0] + dxyz[1] * dxyz[1] + dxyz[2] * dxyz[2];
143 if(r2 < r2max && r2 < h * h)
149 else if(no < Tree->MaxPart + Tree->MaxNodes)
153 if(no < Tree->FirstNonTopLevelNode)
158 fofnode *current = Tree->get_nodep(no, shmrank);
174 Tp->nearest_image_intpos_to_pos(current->
center.da, intpos,
179 double dist = h + 0.5 * len;
181 if(
fabs(dxyz[0]) > dist)
183 if(
fabs(dxyz[1]) > dist)
185 if(
fabs(dxyz[2]) > dist)
190 if(dxyz[0] * dxyz[0] + dxyz[1] * dxyz[1] + dxyz[2] * dxyz[2] > dist * dist)
197 if(p < Tree->MaxPart || (p >= Tree->FirstNonTopLevelNode && p < Tree->MaxPart + Tree->MaxNodes))
201 int task = D->ThisTask + current->
nextnode_shmrank - Tree->TreeSharedMem_ThisTask;
204 Tree->tree_export_node_threads_by_task_and_node(task, nosaved, target, &Thread);
215 else if(no >= Tree->ImportedNodeOffset)
217 Terminate(
"do not expect imported points here");
223 Tree->tree_export_node_threads(no, target, &Thread);
225 no = Tree->get_nextnodep(shmrank)[no - Tree->MaxNodes];
233 out.Distance =
sqrt(r2max);
234 out.MinID = Tp->MinID[Tp->Head[index]];
235 out.MinIDTask = Tp->MinIDTask[Tp->Head[index]];
237 out.DM_Hsml = Tp->PS[index].v.DM_Hsml;
254template <
typename partset>
255double fof<partset>::fof_find_nearest_dmparticle(
void)
265 Tp->fof_nearest_distance = (
MyFloat *)
Mem.mymalloc(
"fof_nearest_distance",
sizeof(
MyFloat) * Tp->NumPart);
266 Tp->fof_nearest_hsml = (
MyFloat *)
Mem.mymalloc(
"fof_nearest_hsml",
sizeof(
MyFloat) * Tp->NumPart);
268 int *TargetList = (
int *)
Mem.mymalloc(
"TargetList", Tp->NumPart *
sizeof(
int));
272 for(
int n = 0; n < Tp->NumPart; n++)
274 if(is_type_secondary_link_type(Tp->P[n].getType()))
277 if(Tp->P[n].getType() == 0 && Tp->SphP[n].Hsml > 0)
278 Tp->fof_nearest_hsml[n] = Tp->SphP[n].Hsml;
280 Tp->fof_nearest_hsml[n] = 0.1 * Tp->LinkL;
282 TargetList[Nsearch++] = n;
286 fofdata_comm<foftree<partset>,
domain<partset>, partset> commpattern{FoFDomain, &FoFNgbTree, Tp};
299 for(
int n = 0; n < Nsearch; n++)
301 int i = TargetList[n];
303 if(Tp->fof_nearest_distance[i] > 1.0e29)
305 if(Tp->fof_nearest_hsml[i] < 4 * Tp->LinkL)
308 TargetList[npleft++] = i;
309 Tp->fof_nearest_hsml[i] *= 2.0;
313 Tp->intpos_to_pos(Tp->P[i].IntPos, pos);
315 printf(
"FOF: i=%d task=%d ID=%d P[i].Type=%d Hsml=%g LinkL=%g nearest=%g pos=(%g|%g|%g)\n", i, ThisTask,
316 (
int)Tp->P[i].ID.get(), Tp->P[i].getType(), Tp->fof_nearest_hsml[i], Tp->LinkL,
317 Tp->fof_nearest_distance[i], pos[0], pos[1], pos[2]);
323 Tp->fof_nearest_distance[i] = 0;
337 mpi_printf(
"FOF: fof-nearest iteration %d: need to repeat for %lld particles. (took = %g sec)\n", iter, ntot,
341 Terminate(
"FOF: failed to converge in fof-nearest\n");
346 Mem.myfree(TargetList);
347 Mem.myfree(Tp->fof_nearest_hsml);
348 Mem.myfree(Tp->fof_nearest_distance);
350 mpi_printf(
"FOF: done finding nearest dm-particle\n");
357#include "../data/simparticles.h"
358template class fof<simparticles>;
360#if defined(LIGHTCONE) && defined(LIGHTCONE_PARTICLES_GROUPS)
361#include "../data/lcparticles.h"
362template 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
double timediff(double t0, double t1)
double getAllocatedBytesInMB(void)
#define MODE_IMPORTED_PARTICLES
#define MODE_LOCAL_PARTICLES
#define LEVEL_ALWAYS_OPEN
#define BITS_FOR_POSITIONS
void sumup_large_ints(int n, int *src, long long *res, MPI_Comm comm)
unsigned char nextnode_shmrank
vector< MyIntPosType > center
unsigned char sibling_shmrank
void myflush(FILE *fstream)