15 #include "gadgetconfig.h"
21 #define TREE_DO_BASE_PM 1
22 #define TREE_DO_HIGHRES_PM 2
23 #define TREE_ACTIVE_CUTTOFF_BASE_PM 4
24 #define TREE_ACTIVE_CUTTOFF_HIGHRES_PM 8
26 #define TREE_MIN_WORKSTACK_SIZE 100000
27 #define TREE_EXPECTED_CYCLES 80
29 #define NODE_TYPE_LOCAL_PARTICLE 0
30 #define NODE_TYPE_TREEPOINT_PARTICLE 1
31 #define NODE_TYPE_FETCHED_PARTICLE 2
32 #define NODE_TYPE_LOCAL_NODE 3
33 #define NODE_TYPE_FETCHED_NODE 4
37 #define NODE_DISCARD 2
39 #define MAX_TREE_ALLOC_FACTOR 30.0
41 #define TAKE_NSLOTS_IN_ONE_GO 32
45 #include "../data/simparticles.h"
46 #include "../data/symtensors.h"
47 #include "../domain/domain.h"
48 #include "../mpi_utils/mpi_utils.h"
49 #include "../tree/tree.h"
67 #if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
70 #if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
73 #if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
76 #if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
86 #if defined(PMGRID) && defined(PLACEHIGHRESREGION)
87 unsigned char overlap_flag : 2;
111 #ifndef HIERARCHICAL_GRAVITY
114 #if defined(PMGRID) && defined(PLACEHIGHRESREGION)
115 unsigned char InsideOutsideFlag : 1;
139 #if defined(PMGRID) && defined(PLACEHIGHRESREGION)
140 unsigned char InsideOutsideFlag : 1;
153 #define HIGHEST_NEEDEDORDER_EWALD_DPHI 1
155 #if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM) || (MULTIPOLE_ORDER >= 2 && defined(FMM)))
156 #undef HIGHEST_NEEDEDORDER_EWALD_DPHI
157 #define HIGHEST_NEEDEDORDER_EWALD_DPHI 2
160 #if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM) || (MULTIPOLE_ORDER >= 3 && defined(FMM)))
161 #undef HIGHEST_NEEDEDORDER_EWALD_DPHI
162 #define HIGHEST_NEEDEDORDER_EWALD_DPHI 3
165 #if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM) || (MULTIPOLE_ORDER >= 4 && defined(FMM)))
166 #undef HIGHEST_NEEDEDORDER_EWALD_DPHI
167 #define HIGHEST_NEEDEDORDER_EWALD_DPHI 4
170 #if((MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM) && defined(EVALPOTENTIAL)) || (MULTIPOLE_ORDER >= 5 && defined(FMM)) || \
172 #undef HIGHEST_NEEDEDORDER_EWALD_DPHI
173 #define HIGHEST_NEEDEDORDER_EWALD_DPHI 5
176 #ifdef EXTRA_HIGH_EWALD_ACCURACY
177 #define EWALD_TAYLOR_ORDER 3
179 #define EWALD_TAYLOR_ORDER 2
189 #if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 4
192 #if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 5
195 #if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 6
198 #if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 7
203 template <
typename partset>
204 class gravtree :
public tree<gravnode, partset, gravpoint_data, foreign_gravpoint_data>
257 #if(MULTIPOLE_ORDER >= 2)
260 #if(MULTIPOLE_ORDER >= 3)
263 #if(MULTIPOLE_ORDER >= 4)
266 #if(MULTIPOLE_ORDER >= 5)
310 void update_node_recursive(
int no,
int sib,
int mode)
override;
311 void exchange_topleafdata(
void)
override;
312 void fill_in_export_points(
gravpoint_data *exp_point,
int i,
int no)
override;
313 void report_log_message(
void)
override;
318 #ifdef ALLOW_DIRECT_SUMMATION
319 void gravity_direct(partset *Pptr,
domain<partset> *Dptr,
int timebin);
327 void short_range_init(
void);
328 void set_mesh_factors(
void);
342 #if(MULTIPOLE_ORDER >= 2)
345 #if(MULTIPOLE_ORDER >= 3)
348 #if(MULTIPOLE_ORDER >= 4)
351 #if(MULTIPOLE_ORDER >= 5)
354 } shortrange_factors[
NTAB + 1];
366 #if(MULTIPOLE_ORDER >= 2)
372 #if(MULTIPOLE_ORDER >= 2)
375 #if(MULTIPOLE_ORDER >= 3)
378 #if(MULTIPOLE_ORDER >= 4)
381 #if(MULTIPOLE_ORDER >= 5)
389 #if(MULTIPOLE_ORDER >= 2)
392 #if(MULTIPOLE_ORDER >= 3)
395 #if(MULTIPOLE_ORDER >= 4)
398 #if(MULTIPOLE_ORDER >= 5)
404 template <
typename T>
407 res.
rinv2 = rinv * rinv;
409 #if(MULTIPOLE_ORDER >= 2)
410 res.rinv3 = res.
rinv2 * rinv;
419 #if(MULTIPOLE_ORDER >= 2)
420 res.fac2 += 3 * res.rinv3;
422 #if(MULTIPOLE_ORDER >= 3)
423 res.fac3 -= 15 * res.rinv3 * rinv;
425 #if(MULTIPOLE_ORDER >= 4)
426 res.fac4 += 105 * res.rinv3 * res.
rinv2;
428 #if(MULTIPOLE_ORDER >= 5)
429 res.fac5 -= 945 * res.rinv3 * res.rinv3;
435 T h2_inv = h_inv * h_inv;
438 #if(MULTIPOLE_ORDER >= 2)
439 T h3_inv = h_inv * h2_inv;
442 #if(MULTIPOLE_ORDER >= 3)
445 #if(MULTIPOLE_ORDER >= 4)
448 #if(MULTIPOLE_ORDER >= 5)
451 if(u <
static_cast<T
>(0.5))
460 #if(MULTIPOLE_ORDER >= 2)
463 #if(MULTIPOLE_ORDER >= 3)
464 gppp = -h3_inv * h_inv * (
static_cast<T
>(
SOFTFAC33) * u +
static_cast<T
>(
SOFTFAC34) * u2);
466 #if(MULTIPOLE_ORDER >= 4)
467 gpppp = -h3_inv * h2_inv * (
static_cast<T
>(
SOFTFAC33) +
static_cast<T
>(
SOFTFAC35) * u);
469 #if(MULTIPOLE_ORDER >= 5)
470 gppppp = -h3_inv * h3_inv *
static_cast<T
>(
SOFTFAC35);
488 #if(MULTIPOLE_ORDER >= 2)
492 #if(MULTIPOLE_ORDER >= 3)
493 gppp = -h3_inv * h_inv *
497 #if(MULTIPOLE_ORDER >= 4)
501 #if(MULTIPOLE_ORDER >= 5)
502 gppppp = -h3_inv * h3_inv * (
static_cast<T
>(
SOFTFAC51) / (u3 * u3) +
static_cast<T
>(
SOFTFAC50));
505 #if(MULTIPOLE_ORDER >= 2)
506 T fac2 = (gpp - rinv * fac1);
509 #if(MULTIPOLE_ORDER >= 3)
510 T fac3 = (gppp - 3 * rinv * fac2);
513 #if(MULTIPOLE_ORDER >= 4)
514 T fac4 = (gpppp - 6 * rinv * fac3 - 3 * rinv * rinv * fac2);
517 #if(MULTIPOLE_ORDER >= 5)
518 T fac5 = (gppppp - 10 * rinv * fac4 - 15 * rinv * rinv * fac3);
524 template <
typename T>
529 res.
fac1 -= rinv * rinv;
537 T h2_inv = h_inv * h_inv;
553 res.
fac1 -= h2_inv * u *
566 template <
typename T>
572 #if(MULTIPOLE_ORDER >= 3)
573 T rinv3 = rinv * rinv * rinv;
574 res.
fac1 = -rinv * rinv;
575 res.fac2 = 3 * rinv3;
581 #if(MULTIPOLE_ORDER >= 3)
582 T h2_inv = h_inv * h_inv;
583 T h3_inv = h2_inv * h_inv;
586 #if(MULTIPOLE_ORDER >= 3)
592 #if(MULTIPOLE_ORDER >= 3)
602 #if(MULTIPOLE_ORDER >= 3)
615 #if(MULTIPOLE_ORDER >= 3)
625 res.fac2 = (gpp - rinv * fac1);
631 inline bool modify_gfactors_pm_multipole(gfactors &res,
const double r,
const double rinv,
const mesh_factors *mfp)
633 double tabentry = mfp->asmthfac * r;
634 int tabindex = (int)tabentry;
638 double w1 = tabentry - tabindex;
642 res.
fac0 += mfp->asmthinv1 * (w0 * shortrange_factors[tabindex].fac0 + w1 * shortrange_factors[tabindex + 1].fac0);
644 res.fac1 += mfp->asmthinv2 * (w0 * shortrange_factors[tabindex].fac1 + w1 * shortrange_factors[tabindex + 1].fac1);
646 #if(MULTIPOLE_ORDER >= 2)
647 res.fac2 += mfp->asmthinv3 * (w0 * shortrange_factors[tabindex].fac2 + w1 * shortrange_factors[tabindex + 1].fac2);
649 #if(MULTIPOLE_ORDER >= 3)
650 res.fac3 += mfp->asmthinv4 * (w0 * shortrange_factors[tabindex].fac3 + w1 * shortrange_factors[tabindex + 1].fac3);
652 #if(MULTIPOLE_ORDER >= 4)
653 res.fac4 += mfp->asmthinv5 * (w0 * shortrange_factors[tabindex].fac4 + w1 * shortrange_factors[tabindex + 1].fac4);
655 #if(MULTIPOLE_ORDER >= 5)
656 res.fac5 += mfp->asmthinv6 * (w0 * shortrange_factors[tabindex].fac5 + w1 * shortrange_factors[tabindex + 1].fac5);
664 inline bool modify_gfactors_pm_monopole(gfactors &res,
const double r,
const double rinv,
const mesh_factors *mfp)
666 double tabentry = mfp->asmthfac * r;
667 int tabindex = (int)tabentry;
671 double w1 = tabentry - tabindex;
675 res.fac0 += mfp->asmthinv1 * (w0 * shortrange_factors[tabindex].fac0 + w1 * shortrange_factors[tabindex + 1].fac0);
677 res.fac1 += mfp->asmthinv2 * (w0 * shortrange_factors[tabindex].fac1 + w1 * shortrange_factors[tabindex + 1].fac1);
void gravity_exchange_forces(void)
tree< gravnode, partset, gravpoint_data, foreign_gravpoint_data > basetree
resultsactiveimported_data * ResultsActiveImported
void set_softenings(void)
This function sets the (comoving) softening length of all particle types in the table All....
void get_gfactors_multipole(gfactors &res, const T r, const T h_max, const T rinv)
void get_gfactors_potential(gfactors &res, const T r, const T hmax, const T rinv)
void get_gfactors_monopole(gfactors &res, const T r, const T h_max, const T rinv)
int TreeSharedMem_ThisTask
gravnode * get_nodep(int no)
MPI_Comm TreeSharedMemComm
ptrdiff_t * TreeNodes_offsets
ptrdiff_t * TreePS_offsets
ptrdiff_t * TreeNextnode_offsets
ptrdiff_t * TreeP_offsets
ptrdiff_t * TreePoints_offsets
void ** TreeSharedMemBaseAddr
ptrdiff_t * TreeForeign_Nodes_offsets
ptrdiff_t * TreeForeign_Points_offsets
ptrdiff_t * TreeSphP_offsets
symtensor3< MyReal > D3phi
symtensor2< MyReal > D2phi
unsigned char getSofteningClass(void)
unsigned char SofteningClass
unsigned char Nextnode_shmrank
int getSofteningClass(void)
unsigned char maxsofttype
unsigned char minsofttype
unsigned char getSofteningClass(void)
unsigned char SofteningClass
vector< MyFloat > GravAccel