MP-Gadget
5.0.1.dev1-76bc7d4726-dirty
|
gravitational tree More...
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <omp.h>
#include "slotsmanager.h"
#include "partmanager.h"
#include "domain.h"
#include "forcetree.h"
#include "checkpoint.h"
#include "walltime.h"
#include "utils/endrun.h"
Go to the source code of this file.
Classes | |
struct | forcetree_params |
struct | NodeCache |
Macros | |
#define | NODECACHE_SIZE (8*12) |
Functions | |
void | init_forcetree_params (const int FastParticleType) |
static ForceTree | force_tree_build (int npart, int mask, DomainDecomp *ddecomp, const int HybridNuGrav, const int DoMoments, const char *EmergencyOutputDir) |
static void | force_treeupdate_pseudos (int no, const ForceTree *tree) |
static void | force_create_node_for_topnode (int no, int topnode, struct NODE *Nodes, const DomainDecomp *ddecomp, int bits, int x, int y, int z, int *nextfree, const int lastnode) |
static void | force_exchange_pseudodata (ForceTree *tree, const DomainDecomp *ddecomp) |
static void | force_insert_pseudo_particles (const ForceTree *tree, const DomainDecomp *ddecomp) |
static void | add_particle_moment_to_node (struct NODE *pnode, int i) |
static int | force_tree_eh_slots_fork (EIBase *event, void *userdata) |
int | force_tree_allocated (const ForceTree *tree) |
void | force_tree_rebuild (ForceTree *tree, DomainDecomp *ddecomp, const int HybridNuGrav, const int DoMoments, const char *EmergencyOutputDir) |
void | force_tree_rebuild_mask (ForceTree *tree, DomainDecomp *ddecomp, int mask, const int HybridNuGrav, const char *EmergencyOutputDir) |
int | get_subnode (const struct NODE *node, const int p_i) |
static int | inside_node (const struct NODE *node, const int p_i) |
static void | init_internal_node (struct NODE *nfreep, struct NODE *parent, int subnode) |
int | get_freenode (int *nnext, struct NodeCache *nc) |
static int | modify_internal_node (int parent, int subnode, int p_toplace, const ForceTree tb, const int HybridNuGrav) |
static int | create_new_node_layer (int firstparent, int p_toplace, const int HybridNuGrav, const ForceTree tb, int *nnext, struct NodeCache *nc) |
int | add_particle_to_tree (int i, int cur_start, const ForceTree tb, const int HybridNuGrav, struct NodeCache *nc, int *nnext) |
int | merge_partial_force_trees (int left, int right, struct NodeCache *nc, int *nnext, const struct ForceTree tb, int HybridNuGrav) |
int | force_tree_create_nodes (const ForceTree tb, const int npart, int mask, DomainDecomp *ddecomp, const int HybridNuGrav) |
int | force_get_father (int no, const ForceTree *tree) |
static int | force_get_sibling (const int sib, const int j, const int *suns) |
static void | force_update_particle_node (int no, const ForceTree *tree) |
static int | force_update_node_recursive (int no, int sib, int level, const ForceTree *tree) |
void | force_update_node_parallel (const ForceTree *tree, const DomainDecomp *ddecomp) |
void | force_update_hmax (int *activeset, int size, ForceTree *tree, DomainDecomp *ddecomp) |
ForceTree | force_treeallocate (int64_t maxnodes, int64_t maxpart, DomainDecomp *ddecomp) |
void | force_tree_free (ForceTree *tree) |
Variables | |
static struct forcetree_params | ForceTreeParams |
gravitational tree
This file contains the computation of the gravitational force by means of a tree. The type of tree implemented is a geometrical oct-tree, starting from a cube encompassing all particles. This cube is automatically found in the ddecomp decomposition, which also splits up the global "top-level" tree along node boundaries, moving the particles of different parts of the tree to separate processors.
Local naming convention: once built it is ForceTree * tree, passed by reference. While the nodes are still being added it is ForceTree tb, passed by value.
Definition in file forcetree.c.
#define NODECACHE_SIZE (8*12) |
Definition at line 336 of file forcetree.c.
|
static |
Definition at line 914 of file forcetree.c.
References NODE::center, NODE::cofm, DMAX, NODE::hmax, NODE::len, NODE::mass, NODE::mom, and P.
Referenced by modify_internal_node().
int add_particle_to_tree | ( | int | i, |
int | cur_start, | ||
const ForceTree | tb, | ||
const int | HybridNuGrav, | ||
struct NodeCache * | nc, | ||
int * | nnext | ||
) |
Definition at line 487 of file forcetree.c.
References create_new_node_layer(), endrun(), ForceTree::firstnode, get_subnode(), ForceTree::lastnode, modify_internal_node(), NMAXCHILD, NodeChild::noccupied, ForceTree::Nodes, NODE::s, and NodeChild::suns.
Referenced by force_tree_create_nodes(), and merge_partial_force_trees().
|
static |
Definition at line 376 of file forcetree.c.
References NODE::ChildType, NODE::f, NODE::father, get_freenode(), get_subnode(), init_internal_node(), ForceTree::lastnode, message(), modify_internal_node(), NODE::mom, NMAXCHILD, NodeCache::nnext_thread, NodeChild::noccupied, NODE_NODE_TYPE, NODECACHE_SIZE, ForceTree::Nodes, P, PARTICLE_NODE_TYPE, NODE::s, NODE::sibling, and NodeChild::suns.
Referenced by add_particle_to_tree().
|
static |
This function recursively creates a set of empty tree nodes which corresponds to the top-level tree for the ddecomp grid. This is done to ensure that this top-level tree is always "complete" so that we can easily associate the pseudo-particles of other CPUs with tree-nodes at a given level in the tree, even when the particle population is so sparse that some of these nodes are actually empty.
Definition at line 818 of file forcetree.c.
References NODE::ChildType, topnode_data::Daughter, endrun(), NODE::f, NODE::father, init_internal_node(), NODE::InternalTopLevel, topnode_data::Leaf, NodeChild::noccupied, NODE_NODE_TYPE, peano_hilbert_key(), NODE::s, NODE::sibling, NodeChild::suns, DomainDecomp::TopLeaves, NODE::TopLevel, DomainDecomp::TopNodes, topleaf_data::treenode, and NodeChild::Types.
Referenced by force_tree_create_nodes().
|
static |
This function communicates the values of the multipole moments of the top-level tree-nodes of the ddecomp grid. This data can then be used to update the pseudo-particles on each CPU accordingly.
Definition at line 1109 of file forcetree.c.
References NODE::ChildType, NODE::cofm, NODE::DependsOnLocalMass, task_data::EndLeaf, endrun(), NODE::f, NODE::father, NODE::hmax, NODE::mass, NODE::mom, myfree, mymalloc, ForceTree::Nodes, NTask, DomainDecomp::NTopLeaves, PSEUDO_NODE_TYPE, task_data::StartLeaf, topleaf_data::Task, DomainDecomp::Tasks, ThisTask, DomainDecomp::TopLeaves, and topleaf_data::treenode.
Referenced by force_tree_build().
int force_get_father | ( | int | no, |
const ForceTree * | tree | ||
) |
Definition at line 905 of file forcetree.c.
References NODE::father, ForceTree::Father, ForceTree::firstnode, and ForceTree::Nodes.
Referenced by _prepare(), check_moments(), check_tree(), effhsml(), force_tree_eh_slots_fork(), ngb_treefind_threads(), set_init_hsml(), and setup_smoothinglengths().
|
static |
Definition at line 934 of file forcetree.c.
Referenced by force_update_node_recursive().
|
static |
this function inserts pseudo-particles which will represent the mass distribution of the other CPUs. Initially, the mass of the pseudo-particles is set to zero, and their coordinate is set to the center of the ddecomp-cell they correspond to. These quantities will be updated later on.
Definition at line 883 of file forcetree.c.
References NODE::ChildType, endrun(), NODE::f, ForceTree::lastnode, NodeChild::noccupied, ForceTree::Nodes, DomainDecomp::NTopLeaves, PSEUDO_NODE_TYPE, NODE::s, NodeChild::suns, topleaf_data::Task, ThisTask, DomainDecomp::TopLeaves, and topleaf_data::treenode.
Referenced by force_tree_build().
int force_tree_allocated | ( | const ForceTree * | tree | ) |
Definition at line 134 of file forcetree.c.
References ForceTree::tree_allocated_flag.
Referenced by _prepare(), force_tree_free(), force_tree_rebuild(), force_tree_rebuild_mask(), sfr_reserve_slots(), and treewalk_run().
|
static |
Constructs the gravitational oct-tree.
The index convention for accessing tree nodes is the following: the indices 0...NumPart-1 reference single particles, the indices firstnode....firstnode +nodes-1 reference tree nodes. ‘Nodes_base’ points to the first tree node, while ‘nodes’ is shifted such that nodes[firstnode] gives the first tree node. Finally, node indices with values 'tb.lastnode' and larger indicate "pseudo particles", i.e. multipole moments of top-level nodes that lie on different CPUs. If such a node needs to be opened, the corresponding particle must be exported to that CPU.
Definition at line 191 of file forcetree.c.
References ALLMASK, ForceTree::BoxSize, part_manager_type::BoxSize, CP, dump_snapshot(), endrun(), ForceTree::firstnode, force_exchange_pseudodata(), force_insert_pseudo_particles(), force_tree_create_nodes(), force_tree_free(), force_treeallocate(), force_treeupdate_pseudos(), force_update_node_parallel(), ForceTreeParams, ForceTree::hmax_computed_flag, Cosmology::HubbleParam, ForceTree::lastnode, ForceTree::mask, part_manager_type::MaxPart, message(), ForceTree::moments_computed_flag, MPI_INT64, MPIU_Any(), mymalloc_usedbytes, myrealloc, ForceTree::Nodes, ForceTree::Nodes_base, DomainDecomp::NTopNodes, ForceTree::numnodes, part_manager_type::NumPart, Cosmology::Omega0, Cosmology::OmegaLambda, PartManager, forcetree_params::TreeAllocFactor, and walltime_measure.
Referenced by force_tree_rebuild(), and force_tree_rebuild_mask().
int force_tree_create_nodes | ( | const ForceTree | tb, |
const int | npart, | ||
int | mask, | ||
DomainDecomp * | ddecomp, | ||
const int | HybridNuGrav | ||
) |
Does initial creation of the nodes for the gravitational oct-tree. mask is a bitfield: Only types whose bit is set are added.
Definition at line 661 of file forcetree.c.
References add_particle_to_tree(), part_manager_type::BoxSize, NODE::center, NODE::ChildType, NODE::cofm, NODE::DependsOnLocalMass, domain_get_topleaf(), slot_info::enabled, task_data::EndLeaf, endrun(), NODE::f, NODE::father, ForceTree::firstnode, force_create_node_for_topnode(), NODE::hmax, slots_manager_type::info, inside_node(), NODE::InternalTopLevel, ForceTree::lastnode, NODE::len, NODE::mass, merge_partial_force_trees(), NODE::mom, NMAXCHILD, NodeCache::nnext_thread, NodeChild::noccupied, NODECACHE_SIZE, ForceTree::Nodes, NodeCache::nrem_thread, part_manager_type::NumPart, P, PARTICLE_NODE_TYPE, PartManager, NODE::s, NODE::sibling, slot_info::size, SlotsManager, task_data::StartLeaf, NodeChild::suns, ta_free, ta_malloc, DomainDecomp::Tasks, ThisTask, DomainDecomp::TopLeaves, NODE::TopLevel, topleaf_data::treenode, NodeChild::Types, and NODE::unused.
Referenced by do_tree_test(), and force_tree_build().
|
static |
Definition at line 110 of file forcetree.c.
References EISlotsFork::child, ForceTree::Father, force_get_father(), NMAXCHILD, NodeChild::noccupied, ForceTree::Nodes, P, EISlotsFork::parent, NODE::s, NodeChild::suns, and NodeChild::Types.
Referenced by force_tree_free(), and force_tree_rebuild().
void force_tree_free | ( | ForceTree * | tree | ) |
This function frees the memory allocated for the tree, i.e. it frees the space allocated by the function force_treeallocate().
Definition at line 1409 of file forcetree.c.
References event_unlisten(), EventSlotsFork, ForceTree::Father, force_tree_allocated(), force_tree_eh_slots_fork(), myfree, ForceTree::Nodes_base, and ForceTree::tree_allocated_flag.
Referenced by _prepare(), do_density_test(), do_force_test(), fof_fof(), force_tree_build(), force_tree_rebuild(), force_tree_rebuild_mask(), metal_return(), run(), run_gravity_test(), runfof(), runpower(), setup_smoothinglengths(), test_rebuild_close(), test_rebuild_flat(), test_rebuild_random(), and turn_on_quasars().
void force_tree_rebuild | ( | ForceTree * | tree, |
DomainDecomp * | ddecomp, | ||
const int | HybridNuGrav, | ||
const int | DoMoments, | ||
const char * | EmergencyOutputDir | ||
) |
Definition at line 140 of file forcetree.c.
References ALLMASK, event_listen(), EventSlotsFork, ForceTree::firstnode, force_tree_allocated(), force_tree_build(), force_tree_eh_slots_fork(), force_tree_free(), ForceTree::lastnode, message(), ForceTree::moments_computed_flag, MPIU_Barrier, mymalloc_usedbytes, ForceTree::NTopLeaves, ForceTree::numnodes, part_manager_type::NumPart, PartManager, and walltime_measure.
Referenced by do_density_test(), do_force_test(), run(), run_gravity_test(), runfof(), runpower(), and setup_smoothinglengths().
void force_tree_rebuild_mask | ( | ForceTree * | tree, |
DomainDecomp * | ddecomp, | ||
int | mask, | ||
const int | HybridNuGrav, | ||
const char * | EmergencyOutputDir | ||
) |
Definition at line 161 of file forcetree.c.
References ForceTree::firstnode, force_tree_allocated(), force_tree_build(), force_tree_free(), ForceTree::lastnode, message(), MPIU_Barrier, ForceTree::NTopLeaves, ForceTree::numnodes, part_manager_type::NumPart, PartManager, and walltime_measure.
Referenced by fof_fof(), metal_return(), and turn_on_quasars().
ForceTree force_treeallocate | ( | int64_t | maxnodes, |
int64_t | maxpart, | ||
DomainDecomp * | ddecomp | ||
) |
This function allocates the memory used for storage of the tree and of auxiliary arrays needed for tree-walk and link-lists. Usually, maxnodes approximately equal to 0.7*maxpart is sufficient to store the tree for up to maxpart particles.
Definition at line 1381 of file forcetree.c.
References endrun(), ForceTree::Father, ForceTree::firstnode, ForceTree::lastnode, mymalloc, ForceTree::nfather, ForceTree::Nodes, ForceTree::Nodes_base, DomainDecomp::NTopLeaves, ForceTree::NTopLeaves, ForceTree::numnodes, DomainDecomp::TopLeaves, ForceTree::TopLeaves, and ForceTree::tree_allocated_flag.
Referenced by force_tree_build(), test_rebuild_close(), test_rebuild_flat(), and test_rebuild_random().
|
static |
This function updates the top-level tree after the multipole moments of the pseudo-particles have been updated.
Definition at line 1195 of file forcetree.c.
References NODE::center, NODE::cofm, endrun(), NODE::f, NODE::father, ForceTree::firstnode, NODE::hmax, NODE::InternalTopLevel, ForceTree::lastnode, NODE::mass, NODE::mom, ForceTree::Nodes, NODE::s, NODE::sibling, and NodeChild::suns.
Referenced by force_tree_build().
void force_update_hmax | ( | int * | activeset, |
int | size, | ||
ForceTree * | tree, | ||
DomainDecomp * | ddecomp | ||
) |
This function updates the hmax-values in tree nodes that hold SPH particles. Since the Hsml-values are potentially changed for active particles in the SPH-density computation, force_update_hmax() should be carried out just before the hydrodynamical SPH forces are computed, i.e. after density().
The purpose of the hmax node is for a symmetric treewalk (currently only the hydro). Particles where P[i].Pos + Hsml pokes beyond the exterior of the tree node may mean that a tree node should be included when it would normally be culled. Therefore we don't really want hmax, we want the maximum amount P[i].Pos + Hsml pokes beyond the tree node.
Definition at line 1271 of file forcetree.c.
References NODE::center, DMAX, task_data::EndLeaf, NODE::father, ForceTree::Father, NODE::hmax, ForceTree::hmax_computed_flag, NODE::len, NODE::mom, myfree, mymalloc, ForceTree::Nodes, NTask, DomainDecomp::NTopLeaves, part_manager_type::NumPart, P, PartManager, task_data::StartLeaf, DomainDecomp::Tasks, ThisTask, DomainDecomp::TopLeaves, topleaf_data::treenode, and walltime_measure.
Referenced by run().
void force_update_node_parallel | ( | const ForceTree * | tree, |
const DomainDecomp * | ddecomp | ||
) |
This routine determines the multipole moments for a given internal node and all its subnodes in parallel, assigning the recursive algorithm to different threads using openmp's task api. The result is stored in tb.Nodes in the sequence of this tree-walk.
Definition at line 1081 of file forcetree.c.
References NODE::ChildType, endrun(), NODE::f, force_update_node_recursive(), force_update_particle_node(), NODE_NODE_TYPE, ForceTree::Nodes, PARTICLE_NODE_TYPE, PSEUDO_NODE_TYPE, NODE::sibling, task_data::StartLeaf, DomainDecomp::Tasks, ThisTask, DomainDecomp::TopLeaves, and topleaf_data::treenode.
Referenced by do_tree_test(), and force_tree_build().
|
static |
this routine determines the multipole moments for a given internal node and all its subnodes using a recursive computation. The result is stored in tb.Nodes in the sequence of this tree-walk.
The function also computes the NextNode and sibling linked lists. The return value is the current tail of the NextNode linked list.
This function is called recursively using openmp tasks. We spawn a new task for a fixed number of levels of the tree.
Definition at line 982 of file forcetree.c.
References NODE::ChildType, NODE::cofm, endrun(), NODE::f, force_get_sibling(), force_update_particle_node(), NODE::hmax, NODE::mass, NODE::mom, NodeChild::noccupied, NODE_NODE_TYPE, ForceTree::Nodes, PARTICLE_NODE_TYPE, NODE::s, NODE::sibling, and NodeChild::suns.
Referenced by force_update_node_parallel().
|
static |
Definition at line 950 of file forcetree.c.
References NODE::center, NODE::ChildType, NODE::cofm, endrun(), NODE::f, NODE::mass, NODE::mom, ForceTree::Nodes, and PARTICLE_NODE_TYPE.
Referenced by force_update_node_parallel(), and force_update_node_recursive().
int get_freenode | ( | int * | nnext, |
struct NodeCache * | nc | ||
) |
Definition at line 345 of file forcetree.c.
References atomic_fetch_and_add(), NodeCache::nnext_thread, NODECACHE_SIZE, and NodeCache::nrem_thread.
Referenced by create_new_node_layer().
int get_subnode | ( | const struct NODE * | node, |
const int | p_i | ||
) |
Definition at line 281 of file forcetree.c.
References NODE::center, and P.
Referenced by add_particle_to_tree(), and create_new_node_layer().
void init_forcetree_params | ( | const int | FastParticleType | ) |
Definition at line 43 of file forcetree.c.
References forcetree_params::FastParticleType, ForceTreeParams, and forcetree_params::TreeAllocFactor.
Referenced by begrun(), setup_density(), setup_tree(), and test_fof().
Definition at line 304 of file forcetree.c.
References NODE::center, NODE::ChildType, NODE::cofm, NODE::DependsOnLocalMass, NODE::f, NODE::father, NODE::hmax, NODE::InternalTopLevel, NODE::len, NODE::mass, NODE::mom, NMAXCHILD, NodeChild::noccupied, PARTICLE_NODE_TYPE, NODE::s, NODE::sibling, NodeChild::suns, NODE::TopLevel, NodeChild::Types, and NODE::unused.
Referenced by create_new_node_layer(), and force_create_node_for_topnode().
|
inlinestatic |
Definition at line 291 of file forcetree.c.
References NODE::center, NODE::len, and P.
Referenced by force_tree_create_nodes().
int merge_partial_force_trees | ( | int | left, |
int | right, | ||
struct NodeCache * | nc, | ||
int * | nnext, | ||
const struct ForceTree | tb, | ||
int | HybridNuGrav | ||
) |
Definition at line 533 of file forcetree.c.
References add_particle_to_tree(), NODE::ChildType, endrun(), NODE::f, NODE::father, ForceTree::firstnode, ForceTree::lastnode, NODE::len, NODE::mom, NodeCache::nnext_thread, NodeChild::noccupied, NODE_NODE_TYPE, ForceTree::Nodes, PARTICLE_NODE_TYPE, NODE::s, NODE::sibling, NodeChild::suns, and NODE::TopLevel.
Referenced by force_tree_create_nodes().
|
static |
Definition at line 361 of file forcetree.c.
References add_particle_moment_to_node(), forcetree_params::FastParticleType, ForceTree::Father, ForceTreeParams, ForceTree::Nodes, P, NODE::s, NodeChild::suns, and NodeChild::Types.
Referenced by add_particle_to_tree(), and create_new_node_layer().
|
static |
Referenced by force_tree_build(), init_forcetree_params(), and modify_internal_node().