enbid-ananke 0.3.1__py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. enbid_ananke/Enbid-2.0/.DS_Store +0 -0
  2. enbid_ananke/Enbid-2.0/COPYING +341 -0
  3. enbid_ananke/Enbid-2.0/COPYRIGHT +18 -0
  4. enbid_ananke/Enbid-2.0/Documentation/enbid.pdf +0 -0
  5. enbid_ananke/Enbid-2.0/Documentation/users-guide.pdf +0 -0
  6. enbid_ananke/Enbid-2.0/Documentation/users-guide.tex +679 -0
  7. enbid_ananke/Enbid-2.0/Documentation/users-guide.tex.flc +4 -0
  8. enbid_ananke/Enbid-2.0/Enbid +0 -0
  9. enbid_ananke/Enbid-2.0/Examples/hernquist1_small/snapshot_ici +0 -0
  10. enbid_ananke/Enbid-2.0/Examples/hernquist1_small/snapshot_ici_typelist +2 -0
  11. enbid_ananke/Enbid-2.0/Examples/uniform_6d_box_4/snapshot_ici +0 -0
  12. enbid_ananke/Enbid-2.0/Examples/uniform_6d_box_4/snapshot_ici_3d.ascii +10000 -0
  13. enbid_ananke/Enbid-2.0/Examples/uniform_6d_box_4/snapshot_ici_6d.ascii +10000 -0
  14. enbid_ananke/Enbid-2.0/parameterfiles/myparameterfile1 +37 -0
  15. enbid_ananke/Enbid-2.0/parameterfiles/myparameterfile2 +37 -0
  16. enbid_ananke/Enbid-2.0/parameterfiles/myparameterfile3 +37 -0
  17. enbid_ananke/Enbid-2.0/parameterfiles/myparameterfile4 +37 -0
  18. enbid_ananke/Enbid-2.0/periodic_lengths.txt +5 -0
  19. enbid_ananke/Enbid-2.0/src/Makefile +43 -0
  20. enbid_ananke/Enbid-2.0/src/allocate.cpp +47 -0
  21. enbid_ananke/Enbid-2.0/src/allocate.o +0 -0
  22. enbid_ananke/Enbid-2.0/src/allvars.cpp +62 -0
  23. enbid_ananke/Enbid-2.0/src/allvars.h +263 -0
  24. enbid_ananke/Enbid-2.0/src/allvars.o +0 -0
  25. enbid_ananke/Enbid-2.0/src/begrun.cpp +361 -0
  26. enbid_ananke/Enbid-2.0/src/begrun.o +0 -0
  27. enbid_ananke/Enbid-2.0/src/density_nd.cpp +130 -0
  28. enbid_ananke/Enbid-2.0/src/density_nd.o +0 -0
  29. enbid_ananke/Enbid-2.0/src/functions.cpp +256 -0
  30. enbid_ananke/Enbid-2.0/src/functions.h +20 -0
  31. enbid_ananke/Enbid-2.0/src/functions.o +0 -0
  32. enbid_ananke/Enbid-2.0/src/init.cpp +299 -0
  33. enbid_ananke/Enbid-2.0/src/init.o +0 -0
  34. enbid_ananke/Enbid-2.0/src/io.cpp +255 -0
  35. enbid_ananke/Enbid-2.0/src/io.o +0 -0
  36. enbid_ananke/Enbid-2.0/src/main.cpp +108 -0
  37. enbid_ananke/Enbid-2.0/src/main.o +0 -0
  38. enbid_ananke/Enbid-2.0/src/ngb_search.cpp +2315 -0
  39. enbid_ananke/Enbid-2.0/src/ngb_search.h +35 -0
  40. enbid_ananke/Enbid-2.0/src/ngb_search.o +0 -0
  41. enbid_ananke/Enbid-2.0/src/nr.cpp +186 -0
  42. enbid_ananke/Enbid-2.0/src/nr.h +13 -0
  43. enbid_ananke/Enbid-2.0/src/nr.o +0 -0
  44. enbid_ananke/Enbid-2.0/src/proto.h +22 -0
  45. enbid_ananke/Enbid-2.0/src/read_ic.cpp +434 -0
  46. enbid_ananke/Enbid-2.0/src/read_ic.o +0 -0
  47. enbid_ananke/Enbid-2.0/src/tree.cpp +973 -0
  48. enbid_ananke/Enbid-2.0/src/tree.h +34 -0
  49. enbid_ananke/Enbid-2.0/src/tree.o +0 -0
  50. enbid_ananke/Enbid-2.0/src/tree_search.cpp +597 -0
  51. enbid_ananke/Enbid-2.0/src/tree_search.o +0 -0
  52. enbid_ananke/__init__.py +318 -0
  53. enbid_ananke/__license__/LICENSE +339 -0
  54. enbid_ananke/__license__/__init__.py +9 -0
  55. enbid_ananke/__metadata__.py +160 -0
  56. enbid_ananke/_builtin_utils.py +62 -0
  57. enbid_ananke/_constants.py +56 -0
  58. enbid_ananke/_defaults.py +36 -0
  59. enbid_ananke/_name.py +10 -0
  60. enbid_ananke/_templates.py +71 -0
  61. enbid_ananke/_version.py +21 -0
  62. enbid_ananke/utils.py +11 -0
  63. enbid_ananke-0.3.1.dist-info/LICENSE +339 -0
  64. enbid_ananke-0.3.1.dist-info/METADATA +33 -0
  65. enbid_ananke-0.3.1.dist-info/RECORD +67 -0
  66. enbid_ananke-0.3.1.dist-info/WHEEL +7 -0
  67. enbid_ananke-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2315 @@
1
+ /***************************************************************************
2
+ ngb_search.cpp - description
3
+ -------------------
4
+ begin : Mon Jan 16 2006
5
+ copyright : (C) 2006 by Sanjib Sharma
6
+ email : ssharma@aip.de
7
+ ***************************************************************************/
8
+
9
+ /***************************************************************************
10
+ * *
11
+ * This program is free software; you can redistribute it and/or modify *
12
+ * it under the terms of the GNU General Public License as published by *
13
+ * the Free Software Foundation; either version 2 of the License, or *
14
+ * (at your option) any later version. *
15
+ * *
16
+ ***************************************************************************/
17
+ #include <stdio.h>
18
+ #include <stdlib.h>
19
+ #include <string>
20
+ #include <math.h>
21
+ #include <algorithm>
22
+ #include "allvars.h"
23
+ #include "nr.h"
24
+ #include "tree.h"
25
+ #include "functions.h"
26
+
27
+
28
+ #define adjust_heap(x,size1)\
29
+ {\
30
+ hi=0;\
31
+ while(1)\
32
+ {\
33
+ hj=((hi+1)<<1);\
34
+ if(hj>size1) break;\
35
+ --hj;\
36
+ if(hj<(size1-1))\
37
+ if(x[hj]<x[hj+1])\
38
+ ++hj;\
39
+ if(x[hi]<x[hj])\
40
+ {\
41
+ ptemp=x[hj];x[hj]=x[hi];x[hi]=ptemp;\
42
+ hi=hj;\
43
+ }\
44
+ else\
45
+ break;\
46
+ }\
47
+ pqHead=x->pq;\
48
+ }
49
+
50
+ inline double periodic(double x,double l2)
51
+ {
52
+ if(x > l2)
53
+ x-=l2*2;
54
+ if(x < -l2)
55
+ x+=l2*2;
56
+ return x;
57
+ }
58
+
59
+
60
+ class rmlist
61
+ {
62
+ public:
63
+ float r,Mass;
64
+ // rmlist(float r1,float Mass1){r=r1; Mass=Mass1;}
65
+ };
66
+
67
+
68
+
69
+ void ngb_treesearch_sphere_metric(int no,struct NODE *nodes1, int NumBucket, int DesNumNgb,struct pqueue* pqxA,bool* imarkA)
70
+ {
71
+ int k,l,i,cell,cp,ct;
72
+ double temp1,temp2,temp3;
73
+ bool b1=0;
74
+ struct pqueue ptemp;
75
+ int hj,hi;
76
+
77
+ // cout<<nodes1<<endl;
78
+
79
+ cell=no;
80
+ while(cell!=ROOT)
81
+ {
82
+ cp=SIBLING(cell,nodes1);
83
+ ct=cp;
84
+ SETNEXT(ct,nodes1);
85
+
86
+ while(1)
87
+ {
88
+
89
+ #ifdef PERIODIC
90
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
91
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
92
+ {
93
+ if(All.boxh[k]>0)
94
+ {
95
+ temp1=(nodes1+cp)->bnd->x[k][1] - searchx[k][0];
96
+ if(temp1<All.boxh[k])
97
+ goto GETNEXT;
98
+ else
99
+ if((temp1-(All.boxh[k]*2))<0)
100
+ goto GETNEXT;
101
+ }
102
+ else
103
+ goto GETNEXT;
104
+ }
105
+
106
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
107
+ {
108
+
109
+ if(All.boxh[k]>0)
110
+ {
111
+ temp1=searchx[k][1]-(nodes1+cp)->bnd->x[k][0];
112
+ if(temp1<All.boxh[k])
113
+ goto GETNEXT;
114
+ else
115
+ if((temp1-(All.boxh[k]*2))<0)
116
+ goto GETNEXT;
117
+ }
118
+ else
119
+ goto GETNEXT;
120
+ }
121
+
122
+ #else
123
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
124
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
125
+ goto GETNEXT;
126
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
127
+ goto GETNEXT;
128
+
129
+ for(k=0,temp3=0; k<ND; ++k)
130
+ {
131
+ temp1=((nodes1+cp)->bnd->x[k][1]-searchcenter[k])*metric[k];
132
+ temp2=((nodes1+cp)->bnd->x[k][0]-searchcenter[k])*metric[k];
133
+ if(temp1>0)
134
+ if(temp2<0)
135
+ continue;
136
+ // break;
137
+ if(temp1<0) {temp1=-temp1; temp2=-temp2;}
138
+ if(temp1<temp2) temp2=temp1;
139
+ temp3+=temp2*temp2;
140
+ if(temp3>pqHead->r) goto GETNEXT;
141
+ }
142
+
143
+ #endif
144
+
145
+ if((nodes1+cp)->count>NumBucket)
146
+ {
147
+ cp=LOWER(cp,nodes1);
148
+ continue;
149
+ }
150
+ else
151
+ {
152
+ b1=0;
153
+ for(l=0; l<(nodes1+cp)->count; ++l)
154
+ {
155
+ i=(nodes1+cp)->lid+l;
156
+ if(imarkA[i]) continue;
157
+ for(k=0,temp2=0; k<ND; ++k)
158
+ {
159
+ #ifdef PERIODIC
160
+ temp1=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
161
+ #else
162
+ temp1=(Part[i].Pos[k]-searchcenter[k])*metric[k];
163
+ #endif
164
+ temp2+=temp1*temp1;
165
+ }
166
+ if(temp2 < pqHead->r)
167
+ {
168
+ imarkA[pqHead->p]=0; imarkA[i]=1;
169
+ pqHead->r=temp2; pqHead->p=i;
170
+ for(k=0;k<ND;++k)
171
+ pqHead->x[k]=Part[i].Pos[k];
172
+ adjust_heap(pqxA,DesNumNgb); b1=1;
173
+ }
174
+ }
175
+ if(b1)
176
+ for(k=0; k<ND; ++k)
177
+ {
178
+ temp1=sqrt(pqHead->r)/metric[k];
179
+ searchx[k][0]=searchcenter[k]-temp1;
180
+ searchx[k][1]=searchcenter[k]+temp1;
181
+ }
182
+ }
183
+
184
+ GETNEXT:
185
+ SETNEXT(cp,nodes1);
186
+ if(cp==ct) break;
187
+ }
188
+ cell=PARENT(cell,nodes1);
189
+
190
+ }
191
+
192
+ return;
193
+ }
194
+
195
+
196
+ void ngb_treesearch_sphere_metric_exact_h(int no,struct NODE *nodes1, int NumBucket, vector<class rmlist> & rmlistv,bool* imarkA)
197
+ {
198
+ int k,l,i,cell,cp,ct;
199
+ double temp1,temp2,temp3;
200
+ class rmlist rmliste;
201
+
202
+ // cout<<nodes1<<endl;
203
+
204
+ cell=no;
205
+ while(cell!=ROOT)
206
+ {
207
+ cp=SIBLING(cell,nodes1);
208
+ ct=cp;
209
+ SETNEXT(ct,nodes1);
210
+
211
+ while(1)
212
+ {
213
+
214
+ #ifdef PERIODIC
215
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
216
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
217
+ {
218
+ if(All.boxh[k]>0)
219
+ {
220
+ temp1=(nodes1+cp)->bnd->x[k][1] - searchx[k][0];
221
+ if(temp1<All.boxh[k])
222
+ goto GETNEXT;
223
+ else
224
+ if((temp1-(All.boxh[k]*2))<0)
225
+ goto GETNEXT;
226
+ }
227
+ else
228
+ goto GETNEXT;
229
+ }
230
+
231
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
232
+ {
233
+
234
+ if(All.boxh[k]>0)
235
+ {
236
+ temp1=searchx[k][1]-(nodes1+cp)->bnd->x[k][0];
237
+ if(temp1<All.boxh[k])
238
+ goto GETNEXT;
239
+ else
240
+ if((temp1-(All.boxh[k]*2))<0)
241
+ goto GETNEXT;
242
+ }
243
+ else
244
+ goto GETNEXT;
245
+ }
246
+
247
+ #else
248
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
249
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
250
+ goto GETNEXT;
251
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
252
+ goto GETNEXT;
253
+
254
+ for(k=0,temp3=0; k<ND; ++k)
255
+ {
256
+ temp1=((nodes1+cp)->bnd->x[k][1]-searchcenter[k])*metric[k];
257
+ temp2=((nodes1+cp)->bnd->x[k][0]-searchcenter[k])*metric[k];
258
+ if(temp1>0)
259
+ if(temp2<0)
260
+ continue;
261
+ // break;
262
+ if(temp1<0) {temp1=-temp1; temp2=-temp2;}
263
+ if(temp1<temp2) temp2=temp1;
264
+ temp3+=temp2*temp2;
265
+ if(temp3>pqHead->r) goto GETNEXT;
266
+ }
267
+
268
+ #endif
269
+
270
+
271
+ if((nodes1+cp)->count>NumBucket)
272
+ {
273
+ cp=LOWER(cp,nodes1);
274
+ continue;
275
+ }
276
+ else
277
+ {
278
+ for(l=0; l<(nodes1+cp)->count; ++l)
279
+ {
280
+ i=(nodes1+cp)->lid+l;
281
+ if(imarkA[i]) continue;
282
+ for(k=0,temp2=0; k<ND; ++k)
283
+ {
284
+ #ifdef PERIODIC
285
+ temp1=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
286
+ #else
287
+ temp1=(Part[i].Pos[k]-searchcenter[k])*metric[k];
288
+ #endif
289
+ temp2+=temp1*temp1;
290
+ }
291
+ if(temp2 < 1.0)
292
+ {
293
+ rmliste.r=temp2;
294
+ rmliste.Mass=Part[i].Mass;
295
+ rmlistv.push_back(rmliste);
296
+ }
297
+ }
298
+ }
299
+
300
+ GETNEXT:
301
+ SETNEXT(cp,nodes1);
302
+ if(cp==ct) break;
303
+ }
304
+ cell=PARENT(cell,nodes1);
305
+
306
+ }
307
+
308
+ return;
309
+ }
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+ void ngb_treesearch_sphere_gmatrix(int no,struct NODE *nodes1, int NumBucket, int DesNumNgb,struct pqueue* pqxA,bool * imarkA)
320
+ {
321
+
322
+
323
+ int k,l,i,j,cell,cp,ct;
324
+ double temp1,temp2,temp3;
325
+ bool b1=0;
326
+ struct pqueue ptemp;
327
+ int hj,hi;
328
+
329
+ // cout<<nodes1<<endl;
330
+
331
+ cell=no;
332
+ while(cell!=ROOT)
333
+ {
334
+ cp=SIBLING(cell,nodes1);
335
+ ct=cp;
336
+ SETNEXT(ct,nodes1);
337
+ while(1)
338
+ {
339
+
340
+ #ifdef PERIODIC
341
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
342
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
343
+ {
344
+ if(All.boxh[k]>0)
345
+ {
346
+ temp1=(nodes1+cp)->bnd->x[k][1] - searchx[k][0];
347
+ if(temp1<All.boxh[k])
348
+ goto GETNEXT;
349
+ else
350
+ if((temp1-(All.boxh[k]*2))<0)
351
+ goto GETNEXT;
352
+ }
353
+ else
354
+ goto GETNEXT;
355
+ }
356
+
357
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
358
+ {
359
+
360
+ if(All.boxh[k]>0)
361
+ {
362
+ temp1=searchx[k][1]-(nodes1+cp)->bnd->x[k][0];
363
+ if(temp1<All.boxh[k])
364
+ goto GETNEXT;
365
+ else
366
+ if((temp1-(All.boxh[k]*2))<0)
367
+ goto GETNEXT;
368
+ }
369
+ else
370
+ goto GETNEXT;
371
+ }
372
+
373
+ #else
374
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
375
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
376
+ goto GETNEXT;
377
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
378
+ goto GETNEXT;
379
+
380
+ for(k=0,temp3=0; k<ND; ++k)
381
+ {
382
+ temp1=((nodes1+cp)->bnd->x[k][1]-searchcenter[k])*metric1[k];
383
+ temp2=((nodes1+cp)->bnd->x[k][0]-searchcenter[k])*metric1[k];
384
+ if(temp1>0)
385
+ if(temp2<0)
386
+ continue;
387
+ // break;
388
+ if(temp1<0) {temp1=-temp1; temp2=-temp2;}
389
+ if(temp1<temp2) temp2=temp1;
390
+ temp3+=temp2*temp2;
391
+ if(temp3>pqHead->r) goto GETNEXT;
392
+ }
393
+
394
+ #endif
395
+
396
+ if((nodes1+cp)->count>NumBucket)
397
+ {
398
+ cp=LOWER(cp,nodes1);
399
+ continue;
400
+ }
401
+ else
402
+ {
403
+ b1=0;
404
+ for(l=0; l<(nodes1+cp)->count; ++l)
405
+ {
406
+ i=(nodes1+cp)->lid+l;
407
+ if(imarkA[i]) continue;
408
+ for(k=0,temp2=0; k<ND; ++k)
409
+ {
410
+
411
+ #ifdef PERIODIC
412
+ for(j=0,temp1=0; j<ND; ++j)
413
+ temp1+=periodic((Part[i].Pos[j]-searchcenter[j]),All.boxh[j])*gmatrix[j][k]*metric1[j];
414
+ #else
415
+ for(j=0,temp1=0; j<ND; ++j)
416
+ temp1+=(Part[i].Pos[j]-searchcenter[j])*gmatrix[j][k]*metric1[j];
417
+ #endif
418
+ temp1=temp1*metric[k];
419
+ temp2+=temp1*temp1;
420
+ }
421
+ if(temp2 < pqHead->r)
422
+ {
423
+ imarkA[pqHead->p]=0; imarkA[i]=1;
424
+ pqHead->r=temp2; pqHead->p=i;
425
+ for(k=0;k<ND;++k)
426
+ pqHead->x[k]=Part[i].Pos[k];
427
+ adjust_heap(pqxA,DesNumNgb); b1=1;
428
+ }
429
+ }
430
+ if(b1)
431
+ {
432
+ temp2=sqrt(pqHead->r);
433
+ for(k=0; k<ND; ++k)
434
+ {
435
+ temp1=temp2/metric1[k];
436
+ searchx[k][0]=searchcenter[k]-temp1;
437
+ searchx[k][1]=searchcenter[k]+temp1;
438
+ }
439
+ }
440
+ }
441
+
442
+ GETNEXT:
443
+ SETNEXT(cp,nodes1);
444
+ if(cp==ct) break;
445
+ }
446
+ cell=PARENT(cell,nodes1);
447
+ }
448
+
449
+ return;
450
+ }
451
+
452
+
453
+ void ngb_treesearch_sphere_nometric(int no, struct NODE* nodes1,int NumBucket, int DesNumNgb,struct pqueue* pqxA,bool * imarkA)
454
+ {
455
+ int k,l,i,cell,cp,ct;
456
+ double temp1,temp2,temp3;
457
+ bool b1=0;
458
+ struct pqueue ptemp;
459
+ int hj,hi;
460
+
461
+ cell=no;
462
+ while(cell!=ROOT)
463
+ {
464
+ cp=SIBLING(cell,nodes1);
465
+ ct=cp;
466
+ SETNEXT(ct,nodes1);
467
+ while(1)
468
+ {
469
+ #ifdef PERIODIC
470
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
471
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
472
+ {
473
+ if(All.boxh[k]>0)
474
+ {
475
+ temp1=(nodes1+cp)->bnd->x[k][1] - searchx[k][0];
476
+ if(temp1<All.boxh[k])
477
+ goto GETNEXT;
478
+ else
479
+ if((temp1-(All.boxh[k]*2))<0)
480
+ goto GETNEXT;
481
+ }
482
+ else
483
+ goto GETNEXT;
484
+ }
485
+
486
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
487
+ {
488
+
489
+ if(All.boxh[k]>0)
490
+ {
491
+ temp1=searchx[k][1]-(nodes1+cp)->bnd->x[k][0];
492
+ if(temp1<All.boxh[k])
493
+ goto GETNEXT;
494
+ else
495
+ if((temp1-(All.boxh[k]*2))<0)
496
+ goto GETNEXT;
497
+ }
498
+ else
499
+ goto GETNEXT;
500
+ }
501
+
502
+ #else
503
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
504
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
505
+ goto GETNEXT;
506
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
507
+ goto GETNEXT;
508
+
509
+ for(k=0,temp3=0; k<ND; ++k)
510
+ {
511
+ temp1=(nodes1[cp].bnd->x[k][1]-searchcenter[k]);
512
+ temp2=(nodes1[cp].bnd->x[k][0]-searchcenter[k]);
513
+ if(temp1>0)
514
+ if(temp2<0)
515
+ continue;
516
+ // break;
517
+ if(temp1<0) {temp1=-temp1; temp2=-temp2;}
518
+ if(temp1<temp2) temp2=temp1;
519
+ temp3+=temp2*temp2;
520
+ if(temp3>pqHead->r) goto GETNEXT;
521
+ }
522
+ #endif
523
+ if((nodes1+cp)->count>NumBucket)
524
+ {
525
+ cp=LOWER(cp,nodes1);
526
+ continue;
527
+ }
528
+ else
529
+ {
530
+ b1=0;
531
+ for(l=0; l<(nodes1+cp)->count; ++l)
532
+ {
533
+ i=(nodes1+cp)->lid+l;
534
+ if(imarkA[i]) continue;
535
+ for(k=0,temp2=0; k<ND; ++k)
536
+ {
537
+
538
+ #ifdef PERIODIC
539
+ temp1=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k]);
540
+ #else
541
+ temp1=(Part[i].Pos[k]-searchcenter[k]);
542
+ #endif
543
+ temp2+=temp1*temp1;
544
+ }
545
+ if(temp2 < pqHead->r)
546
+ {
547
+ imarkA[pqHead->p]=0; imarkA[i]=1;
548
+ pqHead->r=temp2; pqHead->p=i;
549
+ for(k=0;k<ND;++k)
550
+ pqHead->x[k]=Part[i].Pos[k];
551
+ adjust_heap(pqxA,DesNumNgb); b1=1;
552
+ }
553
+ }
554
+ if(b1)
555
+ for(k=0; k<ND; ++k)
556
+ {
557
+ temp1=sqrt(pqHead->r);
558
+ searchx[k][0]=searchcenter[k]-temp1;
559
+ searchx[k][1]=searchcenter[k]+temp1;
560
+ }
561
+ }
562
+
563
+ GETNEXT:
564
+ SETNEXT(cp,nodes1);
565
+ if(cp==ct) break;
566
+ }
567
+ cell=PARENT(cell,nodes1);
568
+ }
569
+
570
+ return;
571
+ }
572
+
573
+
574
+
575
+ void ngb_treesearch_box_metric(int no,struct NODE *nodes1, int NumBucket, int DesNumNgb,struct pqueue* pqxA, bool * imarkA)
576
+ {
577
+ int k,l,i,cell,cp,ct;
578
+ double temp1,temp2;
579
+ bool b1=0;
580
+ struct pqueue ptemp;
581
+ int hj,hi;
582
+
583
+ // cout<<nodes1<<endl;
584
+
585
+ cell=no;
586
+ while(cell!=ROOT)
587
+ {
588
+ cp=SIBLING(cell,nodes1);
589
+ ct=cp;
590
+ SETNEXT(ct,nodes1);
591
+ while(1)
592
+ {
593
+
594
+ #ifdef PERIODIC
595
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
596
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
597
+ {
598
+ if(All.boxh[k]>0)
599
+ {
600
+ temp1=(nodes1+cp)->bnd->x[k][1] - searchx[k][0];
601
+ if(temp1<All.boxh[k])
602
+ goto GETNEXT;
603
+ else
604
+ if((temp1-(All.boxh[k]*2))<0)
605
+ goto GETNEXT;
606
+ }
607
+ else
608
+ goto GETNEXT;
609
+ }
610
+
611
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
612
+ {
613
+
614
+ if(All.boxh[k]>0)
615
+ {
616
+ temp1=searchx[k][1]-(nodes1+cp)->bnd->x[k][0];
617
+ if(temp1<All.boxh[k])
618
+ goto GETNEXT;
619
+ else
620
+ if((temp1-(All.boxh[k]*2))<0)
621
+ goto GETNEXT;
622
+ }
623
+ else
624
+ goto GETNEXT;
625
+ }
626
+ #else
627
+ k=(nodes1+(PARENT(cp,nodes1)))->k1;
628
+ if((nodes1+cp)->bnd->x[k][0] > searchx[k][1])
629
+ goto GETNEXT;
630
+ if((nodes1+cp)->bnd->x[k][1] < searchx[k][0])
631
+ goto GETNEXT;
632
+ #endif
633
+
634
+ if((nodes1+cp)->count>NumBucket)
635
+ {
636
+ cp=LOWER(cp,nodes1);
637
+ continue;
638
+ }
639
+ else
640
+ {
641
+ b1=0;
642
+ for(l=0; l<(nodes1+cp)->count; ++l)
643
+ {
644
+ i=(nodes1+cp)->lid+l;
645
+ if(imarkA[i]) continue;
646
+ for(k=0,temp2=0; k<ND; ++k)
647
+ {
648
+ #ifdef PERIODIC
649
+ temp1=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
650
+ #else
651
+ temp1=(Part[i].Pos[k]-searchcenter[k])*metric[k];
652
+ #endif
653
+ if(temp1<0) temp1=-temp1;
654
+ if(temp2<temp1) temp2=temp1;
655
+ }
656
+ if(temp2 < pqHead->r)
657
+ {
658
+ imarkA[pqHead->p]=0; imarkA[i]=1;
659
+ pqHead->r=temp2; pqHead->p=i;
660
+ for(k=0;k<ND;++k)
661
+ pqHead->x[k]=Part[i].Pos[k];
662
+ adjust_heap(pqxA,DesNumNgb); b1=1;
663
+ }
664
+ }
665
+ if(b1)
666
+ for(k=0; k<ND; ++k)
667
+ {
668
+ temp1=pqHead->r/metric[k];
669
+ searchx[k][0]=searchcenter[k]-temp1;
670
+ searchx[k][1]=searchcenter[k]+temp1;
671
+ }
672
+ }
673
+
674
+ GETNEXT:
675
+ SETNEXT(cp,nodes1);
676
+ if(cp==ct) break;
677
+ }
678
+ cell=PARENT(cell,nodes1);
679
+ }
680
+
681
+ return;
682
+ }
683
+
684
+
685
+
686
+
687
+ float ngb_treedensity_sphere_metric(float xyz[ND],struct NODE *nodes1, int desngb, struct pqueue* pqxA, struct linklist* pqStartA, bool *idoneA,bool *imarkA)
688
+ {
689
+ real u,wk,r; /* search radius */
690
+ int i,j,k,th;
691
+ float rhoxyz;
692
+ double xmin[ND],xmax[ND],temp,temp1;
693
+ struct linklist *pq;
694
+ bool b1,b2=1;
695
+ int b3=1;
696
+ struct pqueue ptemp;
697
+ int hj,hi;
698
+
699
+ /* calculate metric */
700
+ for(j=0; j<ND; j++)
701
+ metric[j]=1.0;
702
+
703
+
704
+ if(All.CubicCells==1)
705
+ {
706
+
707
+ if(ND==6)
708
+ {
709
+
710
+ for(j=0; j<ND; j++)
711
+ searchcenter[j]=0.0;
712
+ ngb_calculate_metric(xyz,nodes1);
713
+ for(j=0; j<ND; j++)
714
+ {
715
+ metric[j]=searchcenter[j];
716
+ }
717
+
718
+
719
+ for(j=0,temp=1.0; j<3; j++)
720
+ temp*=(metric[j]);
721
+ temp=pow(temp,0.3333);
722
+ for(j=0; j<3; j++)
723
+ metric[j]=1/temp;
724
+
725
+
726
+ for(j=3,temp=1.0; j<6; j++)
727
+ temp*=(metric[j]);
728
+ temp=pow(temp,0.3333);
729
+ for(j=3; j<6; j++)
730
+ metric[j]=1/temp;
731
+ }
732
+ }
733
+ else
734
+ {
735
+ for(j=0; j<ND; j++)
736
+ searchcenter[j]=0.0;
737
+ ngb_calculate_metric(xyz,nodes1);
738
+ for(j=0; j<ND; j++)
739
+ {
740
+ metric[j]=1.0/searchcenter[j];
741
+ }
742
+ }
743
+
744
+ for(j=0; j<ND; j++)
745
+ searchcenter[j]=xyz[j];
746
+
747
+
748
+
749
+
750
+ while(b2)
751
+ {
752
+ /* identify the node containing the cell*/
753
+ th=1;
754
+ while(nodes1[th].count>desngb)
755
+ {
756
+ j=nodes1[th].k1;
757
+ if(xyz[j] < nodes1[(LOWER(th,nodes1))].bnd->x[j][1])
758
+ th=(LOWER(th,nodes1));
759
+ else
760
+ th=(UPPER(th,nodes1));
761
+ }
762
+ while(nodes1[th].count<desngb)
763
+ {
764
+ th=PARENT(th,nodes1);
765
+
766
+ }
767
+
768
+
769
+
770
+ if(pnew)
771
+ {
772
+
773
+ for(pq=pqStartA;pq<(pqStartA+desngb);pq++)
774
+ imarkA[pq->p]=0;
775
+
776
+ for(pq=pqStartA,j=0;pq<(pqStartA+desngb);j++,pq++)
777
+ {
778
+ i=nodes1[th].lid+j;
779
+ pq->p=i;
780
+ for(k=0; k<ND; k++)
781
+ pq->x[k]=Part[i].Pos[k];
782
+ imarkA[i]=1;
783
+ }
784
+ }
785
+
786
+
787
+
788
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
789
+ {
790
+ for(j=0,pq->r=0.0; j<ND; j++)
791
+ {
792
+ #ifdef PERIODIC
793
+ temp=periodic((pq->x[j]-searchcenter[j]),All.boxh[j])*metric[j];
794
+ #else
795
+ temp=(pq->x[j]-searchcenter[j])*metric[j];
796
+ #endif
797
+
798
+ pq->r+=temp*temp;
799
+ }
800
+ pqxA[desngb-i-1].pq=pq;
801
+ }
802
+
803
+
804
+ make_heap(pqxA,(pqxA+desngb)); pqHead=pqxA->pq;
805
+
806
+ for(k=0; k<ND; k++)
807
+ {
808
+ temp=sqrt(pqHead->r)/metric[k];
809
+ searchx[k][0]=searchcenter[k]-temp;
810
+ searchx[k][1]=searchcenter[k]+temp;
811
+ }
812
+
813
+
814
+ b1=0;
815
+ if (pnew) k=desngb; else k=0;
816
+ for(j=0; j<nodes1[th].count; j++)
817
+ {
818
+
819
+ i=nodes1[th].lid+j;
820
+ if(imarkA[i]) continue;
821
+ for(k=0,r=0; k<ND; k++)
822
+ {
823
+ #ifdef PERIODIC
824
+ temp=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
825
+ #else
826
+ temp=(Part[i].Pos[k]-searchcenter[k])*metric[k];
827
+ #endif
828
+ r+=temp*temp;
829
+ }
830
+
831
+
832
+ if(r < pqHead->r)
833
+ {
834
+ imarkA[pqHead->p]=0; imarkA[i]=1;
835
+ pqHead->r=r; pqHead->p=i;
836
+ for(k=0;k<ND;k++)
837
+ pqHead->x[k]=Part[i].Pos[k];
838
+ adjust_heap(pqxA,desngb); b1=1;
839
+ }
840
+
841
+ }
842
+
843
+
844
+ if(b1)
845
+ for(k=0; k<ND; k++)
846
+ {
847
+ temp=sqrt(pqHead->r)/metric[k];
848
+ searchx[k][0]=searchcenter[k]-temp;
849
+ searchx[k][1]=searchcenter[k]+temp;
850
+ }
851
+
852
+
853
+
854
+
855
+ ngb_treesearch_sphere_metric(th,nodes1,desngb/2,desngb,pqxA,imarkA);
856
+
857
+
858
+ //----------------------------------------
859
+ b2=0;
860
+ if(b3<2)
861
+ if(All.VolCorr==1)
862
+ {
863
+
864
+ #ifdef PERIODIC
865
+ for(i=0; i<desngb; i++)
866
+ {
867
+
868
+ for(k=0; k<ND; k++)
869
+ {
870
+ temp=periodic((pqStartA[i].x[k]-searchcenter[k]),All.boxh[k]);
871
+ if((i==0)||(temp<xmin[k])) xmin[k]=temp;
872
+ if((i==0)||(temp>xmax[k])) xmax[k]=temp;
873
+ }
874
+ }
875
+
876
+ for(k=0; k<ND; k++)
877
+ {
878
+ xmin[k]+=searchcenter[k];
879
+ xmax[k]+=searchcenter[k];
880
+
881
+ }
882
+ #else
883
+ for(i=0; i<desngb; i++)
884
+ {
885
+
886
+ for(k=0; k<ND; k++)
887
+ {
888
+ if((i==0)||(pqStartA[i].x[k]<xmin[k])) xmin[k]=pqStartA[i].x[k];
889
+ if((i==0)||(pqStartA[i].x[k]>xmax[k])) xmax[k]=pqStartA[i].x[k];
890
+ }
891
+ }
892
+ #endif
893
+
894
+
895
+
896
+
897
+
898
+ for(k=0; k<ND; k++)
899
+ {
900
+ temp=sqrt(pqHead->r)/metric[k];
901
+ searchx[k][0]=searchcenter[k]-temp;
902
+ searchx[k][1]=searchcenter[k]+temp;
903
+ }
904
+
905
+ for(k=0;k<ND;k++)
906
+ {
907
+
908
+ if(All.CubicCells==1)
909
+ temp1=(xmax[k]-xmin[k])*25.0/(All.DesNumNgb);
910
+ else
911
+ temp1=(xmax[k]-xmin[k])*25.0/(All.DesNumNgb);
912
+
913
+
914
+
915
+ if(((searchx[k][1]-xmax[k])>temp1)&&((xmin[k]-searchx[k][0])>temp1))
916
+ {
917
+ b2=1;
918
+ }
919
+ }
920
+
921
+ if(b2)
922
+ for(k=0;k<ND;k++)
923
+ {
924
+ temp=(xmax[k]-xmin[k])*0.5;
925
+ if(xmax[k]!=xmin[k])
926
+ {
927
+ metric[k]=1/temp;
928
+ }
929
+ else
930
+ metric[k]=1/(searchx[k][1]-searchx[k][0]);
931
+
932
+
933
+ }
934
+ b3++;
935
+ }
936
+
937
+
938
+ }
939
+
940
+ //----------------------------------------
941
+
942
+
943
+ pnext=pqHead->p;
944
+ r=pqHead->r;
945
+
946
+ for(i=0,rhoxyz=0; i<desngb; i++)
947
+ {
948
+ u = sqrt(pqStartA[i].r/pqHead->r);
949
+ if(u<1)
950
+ {
951
+ if ((u==0) && (All.KernelBiasCorrection==1))
952
+ u=ND/(1.0+ND);
953
+ k = (int)(u*KERNEL_TABLE);
954
+ wk =( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE); rhoxyz+=wk*Part[pqStartA[i].p].Mass;
955
+ }
956
+
957
+ if(idoneA[pqStartA[i].p]==0)
958
+ if(pqStartA[i].r<r)
959
+ {pnext=pqStartA[i].p;r=pqStartA[i].r;}
960
+
961
+ // cout<<pqStartA[i].p<<" b "<<u<<endl;
962
+
963
+
964
+ }
965
+ if(idoneA[pnext]==1) pnew=1; else pnew=0;
966
+
967
+
968
+ temp=sqrt(pqHead->r);
969
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
970
+ {
971
+ r*=metric[k];
972
+ wk*=temp;
973
+ }
974
+ temp=r/wk;
975
+ // cout<<rhoxyz<<" "<<r<<" "<<wk<<endl;
976
+ rhoxyz*=temp;
977
+ // cout<<rhoxyz<<" "<<All.hsv<<" "<<r/wk<<endl;
978
+
979
+ return rhoxyz;
980
+ }
981
+
982
+
983
+
984
+
985
+
986
+
987
+ float ngb_treedensity_bruteforce(float xyz[ND], int parttype,int desngb, struct pqueue* pqxA, struct linklist* pqStartA)
988
+ {
989
+ real u,wk=0.0,r=0.0; /* search radius */
990
+ int i,j,k,th,l;
991
+ float rhoxyz=0.0;
992
+ double xmin[ND],xmax[ND],temp,temp1,temp2;
993
+ struct linklist *pq;
994
+ // bool b1,b2=1;
995
+ // int b3=1;
996
+ struct pqueue ptemp;
997
+ int hj,hi;
998
+
999
+
1000
+ for(j=0; j<ND; j++)
1001
+ searchcenter[j]=xyz[j];
1002
+
1003
+ th=1;
1004
+ for(pq=pqStartA,j=0;pq<(pqStartA+desngb);j++,pq++)
1005
+ {
1006
+ i=npartc[parttype]+j;
1007
+ pq->p=i;
1008
+ for(k=0; k<ND; k++)
1009
+ pq->x[k]=Part[i].Pos[k];
1010
+ }
1011
+
1012
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
1013
+ {
1014
+
1015
+ if(All.AnisotropicKernel==1)
1016
+ {
1017
+ for(k=0,pq->r=0.0; k<ND; k++)
1018
+ {
1019
+ for(l=0,temp=0; l<ND; ++l)
1020
+ {
1021
+ #ifdef PERIODIC
1022
+ temp+=periodic((pq->x[l]-searchcenter[l]),All.boxh[l])*gmatrix[l][k]*metric1[l];
1023
+ #else
1024
+ temp+=(pq->x[l]-searchcenter[l])*gmatrix[l][k]*metric1[l];
1025
+ #endif
1026
+ }
1027
+ temp=temp*metric[k];
1028
+ pq->r+=temp*temp;
1029
+
1030
+ }
1031
+ }
1032
+ else
1033
+ {
1034
+
1035
+ for(j=0,pq->r=0.0; j<ND; j++)
1036
+ {
1037
+ #ifdef PERIODIC
1038
+ temp=periodic((pq->x[j]-searchcenter[j]),All.boxh[j])*metric[j];
1039
+ #else
1040
+ temp=(pq->x[j]-searchcenter[j])*metric[j];
1041
+ #endif
1042
+ if((All.TypeOfSmoothing==2)||(All.TypeOfSmoothing==3))
1043
+ pq->r+=temp*temp;
1044
+ if((All.TypeOfSmoothing==4)||(All.TypeOfSmoothing==5))
1045
+ {
1046
+ if(temp<0) temp=-temp;
1047
+ if( pq->r<temp) pq->r=temp;
1048
+ }
1049
+ }
1050
+ }
1051
+
1052
+ pqxA[desngb-i-1].pq=pq;
1053
+ }
1054
+
1055
+ make_heap(pqxA,(pqxA+desngb)); pqHead=pqxA->pq;
1056
+
1057
+
1058
+ for(j=desngb; j<npart[parttype]; ++j)
1059
+ {
1060
+ i=npartc[parttype]+j;
1061
+
1062
+ if((All.TypeOfSmoothing==2)||(All.TypeOfSmoothing==3))
1063
+ {
1064
+ if(All.AnisotropicKernel==1)
1065
+ {
1066
+
1067
+ for(k=0,temp2=0; k<ND; k++)
1068
+ {
1069
+ for(l=0,temp=0; l<ND; ++l)
1070
+ {
1071
+ #ifdef PERIODIC
1072
+ temp+=periodic((Part[i].Pos[l]-searchcenter[l]),All.boxh[l])*gmatrix[l][k]*metric1[l];
1073
+ #else
1074
+ temp+=(Part[i].Pos[l]-searchcenter[l])*gmatrix[l][k]*metric1[l];
1075
+ #endif
1076
+ }
1077
+ temp=temp*metric[k];
1078
+ temp2+=temp*temp;
1079
+
1080
+ }
1081
+
1082
+ }
1083
+ else
1084
+ {
1085
+
1086
+
1087
+ for(k=0,temp2=0; k<ND; ++k)
1088
+ {
1089
+ #ifdef PERIODIC
1090
+ temp1=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
1091
+ #else
1092
+ temp1=(Part[i].Pos[k]-searchcenter[k])*metric[k];
1093
+ #endif
1094
+ temp2+=temp1*temp1;
1095
+ }
1096
+
1097
+ }
1098
+ if(temp2 < pqHead->r)
1099
+ {
1100
+ pqHead->r=temp2; pqHead->p=i;
1101
+ adjust_heap(pqxA,desngb);
1102
+ }
1103
+ }
1104
+
1105
+ if((All.TypeOfSmoothing==4)||(All.TypeOfSmoothing==5))
1106
+ {
1107
+ for(k=0,r=0; k<ND; k++)
1108
+ {
1109
+ #ifdef PERIODIC
1110
+ temp=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
1111
+ #else
1112
+ temp=(Part[i].Pos[k]-searchcenter[k])*metric[k];
1113
+ #endif
1114
+
1115
+ if(temp<0) temp=-temp;
1116
+ if(r<temp) r=temp;
1117
+ }
1118
+
1119
+ if(r < pqHead->r)
1120
+ {
1121
+ pqHead->r=r; pqHead->p=i;
1122
+ for(k=0;k<ND;k++)
1123
+ pqHead->x[k]=Part[i].Pos[k];
1124
+ adjust_heap(pqxA,desngb);
1125
+ }
1126
+
1127
+ }
1128
+
1129
+ }
1130
+
1131
+
1132
+
1133
+
1134
+ if((All.TypeOfSmoothing==2)||(All.TypeOfSmoothing==3))
1135
+ {
1136
+
1137
+ // vector<float> rt;
1138
+ // for(i=0,rhoxyz=0; i<desngb; i++)
1139
+ // rt.push_back(sqrt(pqStartA[i].r/pqHead->r));
1140
+ // sort(rt.begin(),rt.end());
1141
+
1142
+
1143
+ for(i=0,rhoxyz=0; i<desngb; i++)
1144
+ {
1145
+ u = sqrt(pqStartA[i].r/pqHead->r);
1146
+ // u=rt[i];
1147
+ if(u<1)
1148
+ {
1149
+ if ((u==0) && (All.KernelBiasCorrection==1))
1150
+ u=ND/(1.0+ND);
1151
+ k = (int)(u*KERNEL_TABLE);
1152
+ wk =( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE); rhoxyz+=wk*(Part[pqStartA[i].p].Mass);
1153
+ }
1154
+ // cout<<i<<" a "<<pqStartA[i].p<<" a "<<u<<endl;
1155
+
1156
+
1157
+ }
1158
+ temp=sqrt(pqHead->r);
1159
+
1160
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
1161
+ {
1162
+ r*=metric[k];
1163
+ if(All.AnisotropicKernel==1)
1164
+ r*=metric1[k];
1165
+ wk*=temp;
1166
+ }
1167
+
1168
+ }
1169
+
1170
+ if((All.TypeOfSmoothing==4)||(All.TypeOfSmoothing==5))
1171
+ {
1172
+ for(i=0,rhoxyz=0; i<desngb; i++)
1173
+ {
1174
+
1175
+ for(k=0,r=0; k<ND; k++)
1176
+ {
1177
+ xmax[k]=pqHead->r/metric[k];
1178
+ #ifdef PERIODIC
1179
+ xmin[k]=periodic((pqStartA[i].x[k] - searchcenter[k]),All.boxh[k]);
1180
+ #else
1181
+ xmin[k]=pqStartA[i].x[k] - searchcenter[k];
1182
+ #endif
1183
+ temp=(xmin[k])/xmax[k];
1184
+ if(temp<0) temp=-temp;
1185
+ xmin[k]=temp;
1186
+ r+=temp;
1187
+ }
1188
+
1189
+ for(l=0,wk=1.0;l<ND;l++)
1190
+ {
1191
+ u=xmin[l];
1192
+
1193
+ if ((r==0.0) && (All.KernelBiasCorrection==1))
1194
+ u=0.5;
1195
+ if(u<1)
1196
+ {
1197
+ k = (int)(u*KERNEL_TABLE);
1198
+ wk*=( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE);
1199
+
1200
+ }
1201
+ else
1202
+ wk=0.0;
1203
+ }
1204
+
1205
+ rhoxyz+=Part[pqStartA[i].p].Mass*wk;
1206
+ }
1207
+ temp=(pqHead->r);
1208
+
1209
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
1210
+ {
1211
+ r*=metric[k];
1212
+ wk*=temp;
1213
+ }
1214
+
1215
+ }
1216
+
1217
+
1218
+
1219
+
1220
+ temp=r/wk;
1221
+ // cout<<rhoxyz<<" "<<r<<" "<<wk<<endl;
1222
+ rhoxyz*=temp;
1223
+
1224
+ // cout<<rhoxyz/All.hsv<<" "<<r<<" "<<wk<<endl;
1225
+
1226
+ return (rhoxyz/All.hsv);
1227
+ }
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+ float ngb_treedensity_sphere_nometric(float xyz[ND],struct NODE *nodes1, int desngb, struct pqueue* pqxA, struct linklist* pqStartA, bool *idoneA,bool *imarkA)
1237
+ {
1238
+ real u,wk,r; /* search radius */
1239
+ int i,j,k,th;
1240
+ float rhoxyz;
1241
+ double temp;
1242
+ struct linklist *pq;
1243
+ bool b1;
1244
+ struct pqueue ptemp;
1245
+ int hj,hi;
1246
+
1247
+
1248
+ /* calculate metric */
1249
+
1250
+ for(j=0; j<ND; j++)
1251
+ searchcenter[j]=xyz[j];
1252
+
1253
+
1254
+ /* identify the node containing the cell*/
1255
+ th=1;
1256
+ while(nodes1[th].count>desngb)
1257
+ {
1258
+ j=nodes1[th].k1;
1259
+ if(xyz[j] < nodes1[(LOWER(th,nodes1))].bnd->x[j][1])
1260
+ th=(LOWER(th,nodes1));
1261
+ else
1262
+ th=(UPPER(th,nodes1));
1263
+ }
1264
+ while(nodes1[th].count<desngb)
1265
+ {
1266
+ th=PARENT(th,nodes1);
1267
+ }
1268
+
1269
+
1270
+ if(pnew)
1271
+ {
1272
+
1273
+ for(pq=pqStartA;pq<(pqStartA+desngb);pq++)
1274
+ imarkA[pq->p]=0;
1275
+
1276
+ for(pq=pqStartA,j=0;pq<(pqStartA+desngb);j++,pq++)
1277
+ {
1278
+ i=nodes1[th].lid+j;
1279
+ pq->p=i;
1280
+ for(k=0; k<ND; k++)
1281
+ pq->x[k]=Part[i].Pos[k];
1282
+ imarkA[i]=1;
1283
+ }
1284
+ }
1285
+
1286
+
1287
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
1288
+ {
1289
+ for(j=0,pq->r=0.0; j<ND; j++)
1290
+ {
1291
+
1292
+ #ifdef PERIODIC
1293
+ temp=periodic((pq->x[j]-searchcenter[j]),All.boxh[j]);
1294
+ #else
1295
+ temp=pq->x[j]-searchcenter[j];
1296
+ #endif
1297
+ pq->r+=temp*temp;
1298
+ }
1299
+ pqxA[desngb-i-1].pq=pq;
1300
+ }
1301
+
1302
+
1303
+ make_heap(pqxA,(pqxA+desngb)); pqHead=pqxA->pq;
1304
+
1305
+
1306
+ for(k=0; k<ND; k++)
1307
+ {
1308
+ temp=sqrt(pqHead->r);
1309
+ searchx[k][0]=searchcenter[k]-temp;
1310
+ searchx[k][1]=searchcenter[k]+temp;
1311
+ }
1312
+
1313
+ b1=0;
1314
+ if (pnew) k=desngb; else k=0;
1315
+ for(j=k; j<nodes1[th].count; j++)
1316
+ {
1317
+ i=nodes1[th].lid+j;
1318
+ if(imarkA[i]) continue;
1319
+ for(k=0,r=0; k<ND; k++)
1320
+ {
1321
+ #ifdef PERIODIC
1322
+ temp=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k]);
1323
+ #else
1324
+ temp=(Part[i].Pos[k]-searchcenter[k]);
1325
+ #endif
1326
+
1327
+ r+=temp*temp;
1328
+ }
1329
+
1330
+ if(r < pqHead->r)
1331
+ {
1332
+ imarkA[pqHead->p]=0; imarkA[i]=1;
1333
+ pqHead->r=r; pqHead->p=i;
1334
+ for(k=0;k<ND;k++)
1335
+ pqHead->x[k]=Part[i].Pos[k];
1336
+ adjust_heap(pqxA,desngb); b1=1;
1337
+ }
1338
+
1339
+ }
1340
+ if(b1)
1341
+ for(k=0; k<ND; k++)
1342
+ {
1343
+ temp=sqrt(pqHead->r);
1344
+ searchx[k][0]=searchcenter[k]-temp;
1345
+ searchx[k][1]=searchcenter[k]+temp;
1346
+ }
1347
+
1348
+
1349
+ ngb_treesearch_sphere_nometric(th,nodes1,desngb/2,desngb,pqxA,imarkA);
1350
+
1351
+
1352
+
1353
+ //----------------------------------------
1354
+
1355
+
1356
+ //----------------------------------------
1357
+
1358
+
1359
+
1360
+ pnext=pqHead->p;
1361
+ r=pqHead->r;
1362
+
1363
+ // vector<float> rt;
1364
+ // for(i=0,rhoxyz=0; i<desngb; i++)
1365
+ // rt.push_back(sqrt(pqStartA[i].r/pqHead->r));
1366
+ // sort(rt.begin(),rt.end());
1367
+
1368
+
1369
+ for(i=0,rhoxyz=0; i<desngb; i++)
1370
+ {
1371
+
1372
+ u = sqrt(pqStartA[i].r/pqHead->r);
1373
+ // u=rt[i];
1374
+ if(u<1)
1375
+ {
1376
+ if ((u==0) && (All.KernelBiasCorrection==1))
1377
+ u=ND/(1.0+ND);
1378
+ k = (int)(u*KERNEL_TABLE);
1379
+ wk =( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE); rhoxyz+=wk*(Part[pqStartA[i].p].Mass);
1380
+ }
1381
+
1382
+ // cout<<i<<" b "<<pqStartA[i].p<<" a "<<u<<endl;
1383
+
1384
+ if(idoneA[pqStartA[i].p]==0)
1385
+ if(pqStartA[i].r<r)
1386
+ {pnext=pqStartA[i].p;r=pqStartA[i].r;}
1387
+
1388
+ }
1389
+ if(idoneA[pnext]==1) pnew=1; else pnew=0;
1390
+
1391
+ temp=sqrt(pqHead->r);
1392
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
1393
+ {
1394
+ // r*=metric[k];
1395
+ wk*=temp;
1396
+ }
1397
+ temp=r/wk;
1398
+ // cout<<rhoxyz<<" "<<r<<" "<<wk<<endl;
1399
+ rhoxyz*=temp;
1400
+ // cout<<rhoxyz<<" "<<All.hsv<<" "<<r/wk<<endl;
1401
+
1402
+
1403
+ return rhoxyz;
1404
+ }
1405
+
1406
+
1407
+
1408
+
1409
+ float ngb_treedensity_sphere_metric_exact_h(float xyz[ND],struct NODE *nodes1, int desngb, struct linklist* pqStartA,bool *imarkA)
1410
+ {
1411
+ real u,wk,r; /* search radius */
1412
+ int i,j,k,th;
1413
+ float rhoxyz;
1414
+ double temp,temp1;
1415
+ struct linklist *pq;
1416
+ vector<class rmlist> rmlistv;
1417
+ class rmlist rmliste;
1418
+
1419
+ /* calculate metric */
1420
+
1421
+ for(j=0; j<ND; j++)
1422
+ searchcenter[j]=xyz[j];
1423
+
1424
+
1425
+ // rmlistv.clear();
1426
+
1427
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
1428
+ {
1429
+ for(j=0,temp1=0.0; j<ND; j++)
1430
+ {
1431
+
1432
+ #ifdef PERIODIC
1433
+ temp=periodic((pq->x[j]-searchcenter[j]),All.boxh[j])*metric[j];
1434
+ #else
1435
+ temp=(pq->x[j]-searchcenter[j])*metric[j];
1436
+ #endif
1437
+ temp1+=temp*temp;
1438
+ }
1439
+ imarkA[pq->p]=1;
1440
+ rmliste.r=temp1;
1441
+ rmliste.Mass=Part[pq->p].Mass;
1442
+ rmlistv.push_back(rmliste);
1443
+ }
1444
+
1445
+
1446
+ /* identify the node containing the cell*/
1447
+ th=1;
1448
+ while(nodes1[th].count>desngb)
1449
+ {
1450
+ j=nodes1[th].k1;
1451
+ if(xyz[j] < nodes1[(LOWER(th,nodes1))].bnd->x[j][1])
1452
+ th=(LOWER(th,nodes1));
1453
+ else
1454
+ th=(UPPER(th,nodes1));
1455
+ }
1456
+ while(nodes1[th].count<desngb)
1457
+ {
1458
+ th=PARENT(th,nodes1);
1459
+ }
1460
+
1461
+
1462
+
1463
+ for(k=0; k<ND; k++)
1464
+ {
1465
+ temp=1/metric[k];
1466
+ searchx[k][0]=searchcenter[k]-temp;
1467
+ searchx[k][1]=searchcenter[k]+temp;
1468
+ }
1469
+
1470
+
1471
+ k=0;
1472
+ for(j=k; j<nodes1[th].count; j++)
1473
+ {
1474
+ i=nodes1[th].lid+j;
1475
+ if(imarkA[i]) continue;
1476
+ for(k=0,r=0; k<ND; k++)
1477
+ {
1478
+ #ifdef PERIODIC
1479
+ temp=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
1480
+ #else
1481
+ temp=(Part[i].Pos[k]-searchcenter[k])*metric[k];
1482
+ #endif
1483
+ r+=temp*temp;
1484
+ }
1485
+ if(r < 1.0)
1486
+ {
1487
+ rmliste.r=r;rmliste.Mass=Part[i].Mass;
1488
+ rmlistv.push_back(rmliste);
1489
+ }
1490
+ }
1491
+
1492
+
1493
+ ngb_treesearch_sphere_metric_exact_h(th,nodes1,desngb/2,rmlistv,imarkA);
1494
+
1495
+
1496
+
1497
+ //----------------------------------------
1498
+
1499
+
1500
+ //----------------------------------------
1501
+
1502
+
1503
+
1504
+ for(i=0,rhoxyz=0; i<int(rmlistv.size()); i++)
1505
+ {
1506
+ u = sqrt(rmlistv[i].r);
1507
+ if(u<1)
1508
+ {
1509
+ if ((u==0) && (All.KernelBiasCorrection==1))
1510
+ u=ND/(1.0+ND);
1511
+ k = (int)(u*KERNEL_TABLE);
1512
+ wk =( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE); rhoxyz+=wk*rmlistv[i].Mass;
1513
+ }
1514
+
1515
+ }
1516
+
1517
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
1518
+ {
1519
+ r*=metric[k];
1520
+ }
1521
+ temp=r/wk;
1522
+ // cout<<rhoxyz<<" "<<r<<" "<<wk<<endl;
1523
+ rhoxyz*=temp;
1524
+ // cout<<rhoxyz<<" "<<All.hsv<<" "<<r/wk<<endl;
1525
+
1526
+
1527
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
1528
+ imarkA[pq->p]=0;
1529
+
1530
+
1531
+ return rhoxyz;
1532
+ }
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+ float ngb_treedensity_box_metric(float xyz[ND],struct NODE *nodes1, int desngb, struct pqueue* pqxA, struct linklist* pqStartA, bool *idoneA,bool *imarkA)
1539
+ {
1540
+ real u,wk,r; /* search radius */
1541
+ int i,j,k,th,l;
1542
+ float rhoxyz;
1543
+ real xmin[ND],xmax[ND],temp,temp1;
1544
+ struct linklist *pq;
1545
+ bool b1,b2=1;
1546
+ int b3=1;
1547
+ struct pqueue ptemp;
1548
+ int hj,hi;
1549
+
1550
+ /* calculate metric */
1551
+ for(j=0; j<ND; j++)
1552
+ metric[j]=1.0;
1553
+
1554
+ if(All.TypeOfSmoothing==5)
1555
+ {
1556
+ if(All.CubicCells==1)
1557
+ {
1558
+ if(ND==6)
1559
+ {
1560
+
1561
+
1562
+ // th=1;
1563
+ // while(nodes1[th].count>1)
1564
+ // {
1565
+ // j=nodes1[th].k1;
1566
+ // if(xyz[j] < nodes1[LOWER(th,nodes1)].bnd->x[j][1])
1567
+ // th=LOWER(th,nodes1);
1568
+ // else
1569
+ // th=UPPER(th,nodes1);
1570
+ // }
1571
+ // for(j=0; j<ND; j++)
1572
+ // {
1573
+ // metric[j]=(nodes1[th].bnd->x[j][1]-nodes1[th].bnd->x[j][0]);
1574
+ // }
1575
+
1576
+
1577
+ for(j=0; j<ND; j++)
1578
+ searchcenter[j]=0.0;
1579
+ ngb_calculate_metric(xyz,nodes1);
1580
+ for(j=0; j<ND; j++)
1581
+ {
1582
+ metric[j]=searchcenter[j];
1583
+ }
1584
+
1585
+
1586
+ for(j=0,temp=1.0; j<3; j++)
1587
+ temp*=(metric[j]);
1588
+ temp=pow(temp,0.3333);
1589
+ for(j=0; j<3; j++)
1590
+ metric[j]=1/temp;
1591
+
1592
+ for(j=3,temp=1.0; j<6; j++)
1593
+ temp*=(metric[j]);
1594
+ temp=pow(temp,0.3333);
1595
+ for(j=3; j<6; j++)
1596
+ metric[j]=1/temp;
1597
+ }
1598
+ }
1599
+ else
1600
+ {
1601
+ for(j=0; j<ND; j++)
1602
+ searchcenter[j]=0.0;
1603
+ ngb_calculate_metric(xyz,nodes1);
1604
+ for(j=0; j<ND; j++)
1605
+ {
1606
+ metric[j]=1.0/searchcenter[j];
1607
+ }
1608
+ }
1609
+ }
1610
+
1611
+
1612
+ for(j=0; j<ND; j++)
1613
+ searchcenter[j]=xyz[j];
1614
+
1615
+
1616
+ while(b2)
1617
+ {
1618
+ /* identify the node containing the cell*/
1619
+ th=1;
1620
+ while(nodes1[th].count>desngb)
1621
+ {
1622
+ j=nodes1[th].k1;
1623
+ if(xyz[j] < nodes1[(LOWER(th,nodes1))].bnd->x[j][1])
1624
+ th=(LOWER(th,nodes1));
1625
+ else
1626
+ th=(UPPER(th,nodes1));
1627
+ }
1628
+ while(nodes1[th].count<desngb)
1629
+ {
1630
+ th=PARENT(th,nodes1);
1631
+ }
1632
+
1633
+
1634
+ if(pnew)
1635
+ {
1636
+ for(pq=pqStartA;pq<(pqStartA+desngb);pq++)
1637
+ imarkA[pq->p]=0;
1638
+
1639
+ for(pq=pqStartA,j=0;pq<(pqStartA+desngb);j++,pq++)
1640
+ {
1641
+ i=nodes1[th].lid+j;
1642
+ pq->p=i;
1643
+ for(k=0; k<ND; k++)
1644
+ pq->x[k]=Part[i].Pos[k];
1645
+ imarkA[i]=1;
1646
+ }
1647
+ }
1648
+
1649
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
1650
+ {
1651
+ for(j=0,pq->r=0.0; j<ND; j++)
1652
+ {
1653
+ #ifdef PERIODIC
1654
+ temp=periodic((pq->x[j]-searchcenter[j]),All.boxh[j])*metric[j];
1655
+ #else
1656
+ temp=(pq->x[j]-searchcenter[j])*metric[j];
1657
+ #endif
1658
+ if(temp<0) temp=-temp;
1659
+ if(pq->r<temp) pq->r=temp;
1660
+ }
1661
+ pqxA[desngb-i-1].pq=pq;
1662
+ }
1663
+
1664
+
1665
+ make_heap(pqxA,(pqxA+desngb)); pqHead=pqxA->pq;
1666
+
1667
+ for(k=0; k<ND; k++)
1668
+ {
1669
+ temp=pqHead->r/metric[k];
1670
+ searchx[k][0]=searchcenter[k]-temp;
1671
+ searchx[k][1]=searchcenter[k]+temp;
1672
+ }
1673
+
1674
+
1675
+ b1=0;
1676
+ if (pnew) k=desngb; else k=0;
1677
+ for(j=0; j<nodes1[th].count; j++)
1678
+ {
1679
+ i=nodes1[th].lid+j;
1680
+ if(imarkA[i]) continue;
1681
+ for(k=0,r=0; k<ND; k++)
1682
+ {
1683
+ #ifdef PERIODIC
1684
+ temp=periodic((Part[i].Pos[k]-searchcenter[k]),All.boxh[k])*metric[k];
1685
+ #else
1686
+ temp=(Part[i].Pos[k]-searchcenter[k])*metric[k];
1687
+ #endif
1688
+
1689
+ if(temp<0) temp=-temp;
1690
+ if(r<temp) r=temp;
1691
+ }
1692
+
1693
+ if(r < pqHead->r)
1694
+ {
1695
+ imarkA[pqHead->p]=0; imarkA[i]=1;
1696
+ pqHead->r=r; pqHead->p=i;
1697
+ for(k=0;k<ND;k++)
1698
+ pqHead->x[k]=Part[i].Pos[k];
1699
+ adjust_heap(pqxA,desngb); b1=1;
1700
+ }
1701
+
1702
+ }
1703
+ if(b1)
1704
+ for(k=0; k<ND; k++)
1705
+ {
1706
+ temp=pqHead->r/metric[k];
1707
+ searchx[k][0]=searchcenter[k]-temp;
1708
+ searchx[k][1]=searchcenter[k]+temp;
1709
+ }
1710
+
1711
+
1712
+
1713
+
1714
+ ngb_treesearch_box_metric(th,nodes1,desngb/2,desngb,pqxA,imarkA);
1715
+
1716
+ //----------------------------------------
1717
+
1718
+
1719
+ if(All.TypeOfSmoothing==4) b3=2;
1720
+ b2=0;
1721
+ if(b3<2)
1722
+ if(All.VolCorr==1)
1723
+ {
1724
+
1725
+ #ifdef PERIODIC
1726
+
1727
+ for(i=0; i<desngb; i++)
1728
+ {
1729
+
1730
+ for(k=0; k<ND; k++)
1731
+ {
1732
+ temp=periodic((pqStartA[i].x[k]-searchcenter[k]),All.boxh[k]);
1733
+ if((i==0)||(temp<xmin[k])) xmin[k]=temp;
1734
+ if((i==0)||(temp>xmax[k])) xmax[k]=temp;
1735
+ }
1736
+ }
1737
+
1738
+ for(k=0; k<ND; k++)
1739
+ {
1740
+ xmin[k]+=searchcenter[k];
1741
+ xmax[k]+=searchcenter[k];
1742
+
1743
+ }
1744
+ #else
1745
+ for(i=0; i<desngb; i++)
1746
+ {
1747
+
1748
+ for(k=0; k<ND; k++)
1749
+ {
1750
+ if((i==0)||(pqStartA[i].x[k]<xmin[k])) xmin[k]=pqStartA[i].x[k];
1751
+ if((i==0)||(pqStartA[i].x[k]>xmax[k])) xmax[k]=pqStartA[i].x[k];
1752
+ }
1753
+ }
1754
+ #endif
1755
+
1756
+
1757
+ for(k=0; k<ND; k++)
1758
+ {
1759
+ temp=sqrt(pqHead->r)/metric[k];
1760
+ searchx[k][0]=searchcenter[k]-temp;
1761
+ searchx[k][1]=searchcenter[k]+temp;
1762
+ }
1763
+
1764
+ for(k=0;k<ND;k++)
1765
+ {
1766
+
1767
+ if(All.CubicCells==1)
1768
+ temp1=(xmax[k]-xmin[k])*15.0/(All.DesNumNgb);
1769
+ else
1770
+ temp1=(xmax[k]-xmin[k])*15.0/(All.DesNumNgb);
1771
+
1772
+ if(((searchx[k][1]-xmax[k])>temp1)&&((xmin[k]-searchx[k][0])>temp1))
1773
+ {
1774
+ b2=1;
1775
+ }
1776
+
1777
+ }
1778
+
1779
+ if(b2)
1780
+ for(k=0;k<ND;k++)
1781
+ {
1782
+ // temp=(xmax[k]-xmin[k])*0.5;
1783
+ // metric[k]=1/temp;
1784
+ temp=(xmax[k]-xmin[k])*0.5;
1785
+ if(xmax[k]!=xmin[k])
1786
+ {
1787
+ metric[k]=1/temp;
1788
+ }
1789
+ else
1790
+ metric[k]=1/(searchx[k][1]-searchx[k][0]);
1791
+
1792
+
1793
+ }
1794
+
1795
+ // if(b3>5)
1796
+ // cout<<b3<<endl;
1797
+ b3++;
1798
+ }
1799
+ }
1800
+
1801
+ //----------------------------------------
1802
+
1803
+
1804
+
1805
+
1806
+ pnext=pqHead->p;
1807
+ r=pqHead->r;
1808
+
1809
+
1810
+ for(i=0,rhoxyz=0; i<desngb; i++)
1811
+ {
1812
+
1813
+ for(k=0,r=0; k<ND; k++)
1814
+ {
1815
+ xmax[k]=pqHead->r/metric[k];
1816
+ #ifdef PERIODIC
1817
+ xmin[k]=periodic((pqStartA[i].x[k] - searchcenter[k]),All.boxh[k]);
1818
+ #else
1819
+ xmin[k]=pqStartA[i].x[k] - searchcenter[k];
1820
+ #endif
1821
+ temp=(xmin[k])/xmax[k];
1822
+ if(temp<0) temp=-temp;
1823
+ xmin[k]=temp;
1824
+ r+=temp;
1825
+ }
1826
+
1827
+ for(l=0,wk=1.0;l<ND;l++)
1828
+ {
1829
+ u=xmin[l];
1830
+
1831
+ if ((r==0.0) && (All.KernelBiasCorrection==1))
1832
+ u=0.5;
1833
+ if(u<1)
1834
+ {
1835
+ k = (int)(u*KERNEL_TABLE);
1836
+ wk*=( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE);
1837
+
1838
+ }
1839
+ else
1840
+ wk=0.0;
1841
+ }
1842
+
1843
+
1844
+
1845
+ rhoxyz+=Part[pqStartA[i].p].Mass*wk;
1846
+
1847
+
1848
+
1849
+ if(idoneA[pqStartA[i].p]==0)
1850
+ if(pqStartA[i].r<r)
1851
+ {pnext=pqStartA[i].p;r=pqStartA[i].r;}
1852
+
1853
+
1854
+
1855
+ }
1856
+ if(idoneA[pnext]==1) pnew=1; else pnew=0;
1857
+
1858
+
1859
+ temp=pqHead->r;
1860
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
1861
+ {
1862
+ r*=metric[k];
1863
+ wk*=temp;
1864
+ }
1865
+ temp=r/wk;
1866
+ // cout<<rhoxyz<<" "<<r<<" "<<wk<<endl;
1867
+ rhoxyz*=temp;
1868
+
1869
+
1870
+ // cout<<"density"<<rhoxyz<<endl;
1871
+ // endrun(10);
1872
+
1873
+ return rhoxyz;
1874
+ }
1875
+
1876
+
1877
+
1878
+
1879
+
1880
+
1881
+
1882
+
1883
+ float ngb_treedensity_sphere_gmatrix(float xyz[ND],struct NODE *nodes1, int desngb, struct pqueue* pqxA, struct linklist* pqStartA, bool *idoneA,bool *imarkA)
1884
+ {
1885
+ real u,wk,r; /* search radius */
1886
+ int i,j,k,th,l;
1887
+ float rhoxyz;
1888
+ double temp;
1889
+ struct linklist *pq;
1890
+ bool b1;
1891
+
1892
+
1893
+ struct pqueue ptemp;
1894
+ int hj,hi;
1895
+
1896
+ /* calculate metric */
1897
+
1898
+ for(j=0; j<ND; j++)
1899
+ searchcenter[j]=xyz[j];
1900
+
1901
+
1902
+ /* identify the node containing the cell*/
1903
+ th=1;
1904
+ while(nodes1[th].count>desngb)
1905
+ {
1906
+ j=nodes1[th].k1;
1907
+ if(xyz[j] < nodes1[(LOWER(th,nodes1))].bnd->x[j][1])
1908
+ th=(LOWER(th,nodes1));
1909
+ else
1910
+ th=(UPPER(th,nodes1));
1911
+ }
1912
+ while(nodes1[th].count<desngb)
1913
+ {
1914
+ th=PARENT(th,nodes1);
1915
+ }
1916
+
1917
+ // pnew=1;
1918
+ if(pnew)
1919
+ {
1920
+ for(pq=pqStartA,j=0;pq<(pqStartA+desngb);j++,pq++)
1921
+ {
1922
+ i=nodes1[th].lid+j;
1923
+ if(imarkA[i]==1) continue;
1924
+ imarkA[pq->p]=0;
1925
+ pq->p=i;
1926
+ for(k=0; k<ND; k++)
1927
+ pq->x[k]=Part[i].Pos[k];
1928
+ imarkA[i]=1;
1929
+ }
1930
+ }
1931
+
1932
+ for(pq=pqStartA,i=0;pq<(pqStartA+desngb);++i,pq++)
1933
+ {
1934
+ for(j=0,pq->r=0.0; j<ND; j++)
1935
+ {
1936
+ for(l=0,temp=0; l<ND; ++l)
1937
+ {
1938
+ #ifdef PERIODIC
1939
+ temp+=periodic((pq->x[l]-searchcenter[l]),All.boxh[l])*gmatrix[l][j]*metric1[l];
1940
+ #else
1941
+ temp+=(pq->x[l]-searchcenter[l])*gmatrix[l][j]*metric1[l];
1942
+ #endif
1943
+ }
1944
+
1945
+ temp=temp*metric[j];
1946
+ pq->r+=temp*temp;
1947
+ }
1948
+ pqxA[desngb-i-1].pq=pq;
1949
+ }
1950
+
1951
+
1952
+ make_heap(pqxA,(pqxA+desngb)); pqHead=pqxA->pq;
1953
+
1954
+ for(k=0; k<ND; k++)
1955
+ {
1956
+ temp=sqrt(pqHead->r)/metric1[k];
1957
+ searchx[k][0]=searchcenter[k]-temp;
1958
+ searchx[k][1]=searchcenter[k]+temp;
1959
+ }
1960
+
1961
+
1962
+ b1=0;
1963
+ if (pnew) k=desngb; else k=0;
1964
+ for(j=0; j<nodes1[th].count; j++)
1965
+ {
1966
+ i=nodes1[th].lid+j;
1967
+ if(imarkA[i]) continue;
1968
+ for(k=0,r=0; k<ND; k++)
1969
+ {
1970
+ for(l=0,temp=0; l<ND; ++l)
1971
+ {
1972
+ #ifdef PERIODIC
1973
+ temp+=periodic((Part[i].Pos[l]-searchcenter[l]),All.boxh[l])*gmatrix[l][k]*metric1[l];
1974
+ #else
1975
+ temp+=(Part[i].Pos[l]-searchcenter[l])*gmatrix[l][k]*metric1[l];
1976
+ #endif
1977
+ }
1978
+ temp=temp*metric[k];
1979
+ r+=temp*temp;
1980
+
1981
+ }
1982
+
1983
+ if(r < pqHead->r)
1984
+ {
1985
+ imarkA[pqHead->p]=0; imarkA[i]=1;
1986
+ pqHead->r=r; pqHead->p=i;
1987
+ for(k=0;k<ND;k++)
1988
+ pqHead->x[k]=Part[i].Pos[k];
1989
+ adjust_heap(pqxA,desngb); b1=1;
1990
+
1991
+ }
1992
+
1993
+ }
1994
+ if(b1)
1995
+ for(k=0; k<ND; k++)
1996
+ {
1997
+ temp=sqrt(pqHead->r)/metric1[k];
1998
+ searchx[k][0]=searchcenter[k]-temp;
1999
+ searchx[k][1]=searchcenter[k]+temp;
2000
+ }
2001
+
2002
+ // cout<<" c "<<pqHead->r<<endl;
2003
+
2004
+
2005
+ ngb_treesearch_sphere_gmatrix(th,nodes1,desngb/2,desngb,pqxA,imarkA);
2006
+ //----------------------------------------
2007
+
2008
+ pnext=pqHead->p;
2009
+ r=pqHead->r;
2010
+
2011
+
2012
+ for(k=0,temp=metric[0];k<ND;k++)
2013
+ if(temp>metric[k]) temp=metric[k];
2014
+
2015
+
2016
+ // int ii=0;
2017
+ for(i=0,rhoxyz=0; i<desngb; i++)
2018
+ {
2019
+
2020
+
2021
+ u = sqrt(pqStartA[i].r/pqHead->r);
2022
+
2023
+
2024
+ if(u<1)
2025
+ {
2026
+ if ((u==0) && (All.KernelBiasCorrection==1))
2027
+ u=ND/(1.0+ND);
2028
+ k = (int)(u*KERNEL_TABLE);
2029
+ wk =( Kernel[k] + (Kernel[k+1]-Kernel[k])*(u-KernelRad[k])*KERNEL_TABLE); rhoxyz+=wk*Part[pqStartA[i].p].Mass;
2030
+ }
2031
+
2032
+ // cout<<i<<" "<<pqStartA[i].p<<" a "<<u<<endl;
2033
+
2034
+
2035
+ if(idoneA[pqStartA[i].p]==0)
2036
+ if(pqStartA[i].r<r)
2037
+ {pnext=pqStartA[i].p;r=pqStartA[i].r;}
2038
+ // cout<<pqStartA[i].p<<" b "<<u<<endl;
2039
+
2040
+ }
2041
+ if(idoneA[pnext]==1) pnew=1; else pnew=0;
2042
+
2043
+
2044
+ temp=sqrt(pqHead->r);
2045
+ for(k=0,r=1.0,wk=1.0;k<ND;k++)
2046
+ {
2047
+ r*=metric[k]*metric1[k];
2048
+ wk*=temp;
2049
+ }
2050
+ temp=r/wk;
2051
+ // cout<<rhoxyz<<" "<<r<<" "<<wk<<endl;
2052
+ rhoxyz*=temp;
2053
+ // cout<<rhoxyz<<endl;
2054
+
2055
+
2056
+ return rhoxyz;
2057
+ }
2058
+
2059
+
2060
+
2061
+
2062
+
2063
+
2064
+
2065
+ float anisokernel_density(float xyz[ND],struct NODE *nodes1, int desngbA, struct pqueue* pqxA, struct linklist* pqStartA, bool *idoneA,bool *imarkA, int desngbB, struct pqueue* pqxB, struct linklist* pqStartB, bool *idoneB,bool *imarkB)
2066
+ {
2067
+ int n,k,l,nrot;
2068
+ double dx[ND],dxcm[ND],mtot=0.0,ht1,rcm;
2069
+ float rhoxyz;
2070
+
2071
+ for(k=0;k<ND;k++)
2072
+ dxcm[k]=0.0;
2073
+
2074
+ if(All.TypeOfSmoothing==2)
2075
+ {
2076
+ rhoxyz=ngb_treedensity_sphere_nometric(xyz,nodes1,desngbA,pqxA,pqStartA,idoneA,imarkA);
2077
+ for(k=0;k<ND;k++)
2078
+ metric1[k]=1.0;
2079
+ }
2080
+ if(All.TypeOfSmoothing==3)
2081
+ {
2082
+ rhoxyz=ngb_treedensity_sphere_metric(xyz,nodes1,desngbA,pqxA,pqStartA,idoneA,imarkA);
2083
+ for(k=0;k<ND;k++)
2084
+ metric1[k]=metric[k];
2085
+ }
2086
+
2087
+
2088
+ // for(k=0;k<ND;k++)
2089
+ // cout<<sqrt(pqHead->r)/metric[k]<<" "<<endl;
2090
+
2091
+ for(k=1;k<=ND;k++)
2092
+ for(l=1;l<=ND;l++)
2093
+ mrho[k][l]=0.0;
2094
+
2095
+ // Calculate the center of mass dxcm[k]
2096
+ for(n=0; n<desngbA; n++)
2097
+ {
2098
+ for(k=0;k<ND;k++)
2099
+ {
2100
+ #ifdef PERIODIC
2101
+ dx[k] = periodic((xyz[k] - pqStartA[n].x[k]),All.boxh[k]);
2102
+ #else
2103
+ dx[k] = xyz[k] - pqStartA[n].x[k];
2104
+ #endif
2105
+
2106
+ dxcm[k]+=dx[k]*Part[pqStartA[n].p].Mass;
2107
+ }
2108
+ mtot +=Part[pqStartA[n].p].Mass;
2109
+ }
2110
+
2111
+ for(k=0,rcm=0.0;k<ND;k++)
2112
+ {
2113
+ dxcm[k]=dxcm[k]/mtot;
2114
+ rcm+=dxcm[k]*dxcm[k];
2115
+ }
2116
+ rcm=sqrt(rcm);
2117
+
2118
+
2119
+
2120
+
2121
+ // Calculate the covariance matrix
2122
+ for(n=0; n<desngbA; n++)
2123
+ {
2124
+ for(k=0;k<ND;k++)
2125
+ {
2126
+ #ifdef PERIODIC
2127
+ dx[k] = periodic((xyz[k] - pqStartA[n].x[k]),All.boxh[k]);
2128
+ #else
2129
+ dx[k] = xyz[k] - pqStartA[n].x[k];
2130
+ #endif
2131
+ dx[k] =dx[k]-dxcm[k];
2132
+ }
2133
+
2134
+ for(k=1;k<=ND;k++)
2135
+ for(l=1;l<=ND;l++)
2136
+ {
2137
+ mrho[k][l]+=dx[k-1]*dx[l-1]*Part[pqStartA[n].p].Mass;
2138
+ }
2139
+ }
2140
+
2141
+
2142
+ for(k=1;k<=ND;k++)
2143
+ for(l=1;l<=ND;l++)
2144
+ {
2145
+ mrho[k][l]=mrho[k][l]*metric1[k-1]*metric1[l-1]/(mtot*sqrt(pqHead->r*pqHead->r));
2146
+ // cout<<k<<" "<<l<<" "<<mrho[k][l]<<endl;
2147
+
2148
+ }
2149
+
2150
+
2151
+ // Calculate the transoformation matrix "ve" of unit covariance and update scaling "d"
2152
+ jacobi(mrho,ND,d,ve,&nrot);
2153
+
2154
+ for(k=1;k<=ND;k++)
2155
+ {
2156
+ d[k]=fabs(sqrt(d[k]));
2157
+ }
2158
+
2159
+
2160
+ ht1=a_max(d,1,ND);
2161
+ for(k=1;k<=ND;k++)
2162
+ {
2163
+ d[k]=d[k]/ht1;
2164
+ }
2165
+
2166
+
2167
+ // for(k=1;k<=ND;k++)
2168
+ // for(l=1;l<=ND;l++)
2169
+ // cout<<k<<" "<<l<<" ve "<<ve[k][l]<<endl;
2170
+
2171
+
2172
+
2173
+ if(a_min(d,1,ND)<All.Anisotropy)
2174
+ {
2175
+ for(k=1;k<=ND;k++)
2176
+ {
2177
+ if(d[k]<All.Anisotropy)
2178
+ d[k]=All.Anisotropy;
2179
+ }
2180
+ for(k=1;k<=ND;k++)
2181
+ for(l=1;l<=ND;l++)
2182
+ {
2183
+ ve[k][l]=0.0;
2184
+ if(k==l) ve[k][l]=1.0;
2185
+ }
2186
+ }
2187
+
2188
+
2189
+ for(k=1;k<=ND;k++)
2190
+ for(l=1;l<=ND;l++)
2191
+ {
2192
+ gmatrix[k-1][l-1]=ve[k][l];
2193
+ // gmatrix[k-1][l-1]=0.0;
2194
+ // if(k==l)gmatrix[k-1][l-1]=1.0;
2195
+ }
2196
+
2197
+ for(k=1,ht1=1.0/d[1];k<=ND;k++)
2198
+ {
2199
+ metric[k-1]=1.0/d[k];
2200
+ if(ht1>metric[k-1])
2201
+ ht1=metric[k-1];
2202
+ }
2203
+
2204
+ for(k=0;k<ND;k++)
2205
+ {
2206
+ metric[k]=metric[k]/ht1;
2207
+ // metric[k]=1.0;
2208
+ // cout<<" a "<<1/metric[k]<<" "<<metric[k]<<endl;
2209
+ }
2210
+
2211
+
2212
+
2213
+ rhoxyz=ngb_treedensity_sphere_gmatrix(xyz,nodes1,desngbB,pqxB,pqStartB,idoneB,imarkB);
2214
+
2215
+
2216
+
2217
+ // cout<<rhoxyz<<endl;
2218
+ return rhoxyz;
2219
+ }
2220
+
2221
+
2222
+ void create_linklist(struct pqueue* &pqx,struct linklist* &pqStart,bool* &imark,bool* &idone,int desngb,int numpart)
2223
+ {
2224
+ int i;
2225
+ pqStart=new linklist[desngb];
2226
+ pqx=new pqueue[desngb];
2227
+ for(i=0;i<desngb;++i)
2228
+ pqx[i].pq=pqStart+i;
2229
+ imark= new bool[numpart];
2230
+ idone= new bool[numpart];
2231
+ for(i=0; i<numpart; i++)
2232
+ {idone[i]=0; }
2233
+ }
2234
+
2235
+
2236
+
2237
+ void initialize_linklist(struct linklist* pqStart,bool* imark,int iStart,int desngb,int numpart)
2238
+ {
2239
+ int k,ji;
2240
+ struct linklist *pq;
2241
+ for(k=0; k<numpart; k++)
2242
+ imark[k]=0;
2243
+ // for(j=0; j<parttype; j++)
2244
+ // i+=npart[j];
2245
+
2246
+ for(pq=pqStart,ji=iStart;pq<(pqStart+desngb);ji++,pq++)
2247
+ {
2248
+ // cout<<i<<" "<<ji<<" "<<nodes1<<" "<<trees[j]<<endl;
2249
+ pq->p=ji;
2250
+ for(k=0; k<ND; k++)
2251
+ pq->x[k]=Part[ji].Pos[k];
2252
+ imark[ji]=1;
2253
+ }
2254
+
2255
+ }
2256
+
2257
+
2258
+ float density_general(float xyz[ND],struct NODE *nodes1, int desngbA, struct pqueue* pqxA, struct linklist* pqStartA, bool *idoneA,bool *imarkA, int desngbB, struct pqueue* pqxB, struct linklist* pqStartB, bool *idoneB,bool *imarkB)
2259
+ {
2260
+ float Density=0;
2261
+ if(All.AnisotropicKernel==1)
2262
+ {
2263
+ Density= anisokernel_density(xyz, nodes1,desngbA,pqxA,pqStartA,idoneA,imarkA,desngbB,pqxB,pqStartB,idoneB,imarkB)/All.hsv;
2264
+ }
2265
+ else
2266
+ {
2267
+ switch (All.TypeOfSmoothing)
2268
+ {
2269
+ case 0:
2270
+ Density=ngb_treedensity_raw(xyz,nodes1)/All.hsv;
2271
+ break;
2272
+ case 1:
2273
+ Density=ngb_treedensity_fiestas(xyz,nodes1)/All.hsv;
2274
+ break;
2275
+ case 2:
2276
+ Density= ngb_treedensity_sphere_nometric(xyz, nodes1,desngbB,pqxB,pqStartB,idoneB,imarkB)/All.hsv;
2277
+ break;
2278
+ case 3:
2279
+ Density= ngb_treedensity_sphere_metric(xyz, nodes1,desngbB,pqxB,pqStartB,idoneB,imarkB)/All.hsv;
2280
+ break;
2281
+ case 4:
2282
+ Density= ngb_treedensity_box_metric(xyz, nodes1,desngbB,pqxB,pqStartB,idoneB,imarkB)/All.hsv;
2283
+ break;
2284
+ case 5:
2285
+ Density= ngb_treedensity_box_metric(xyz, nodes1,desngbB,pqxB,pqStartB,idoneB,imarkB)/All.hsv;
2286
+ break;
2287
+ default:
2288
+ cout<<"Usage: TypeOfSmoothing 0 to 6"<<endl;
2289
+ endrun(10);
2290
+ break;
2291
+ }
2292
+ }
2293
+ return Density;
2294
+ }
2295
+
2296
+
2297
+
2298
+
2299
+ void print_list(struct linklist *pq1,int size1)
2300
+ {
2301
+ struct linklist *pq;
2302
+ int i;
2303
+ cout<<" List "<<endl;
2304
+ pq=pq1;
2305
+ for(i=0;i<size1;i++)
2306
+ {
2307
+ cout<<i<<" "<<pq<<" "<<" "<<pq->r<<" "<<pq->p<<endl;
2308
+ if(i!=(size1-1))
2309
+ pq++;
2310
+ }
2311
+ cout<<" complete "<<endl;
2312
+ }
2313
+
2314
+
2315
+