Module: SpaceCharge
The SpaceCharge module bundles different approaches to efficiently simulate the electric interaction between particles (space charge).
The module contains submodules implementing individual calculation approaches, generalized interface classes are located in the module itself:
-
class FieldCalculator
Subclassed by BTree::ParallelTree, BTree::Tree, SpaceCharge::GenericSpaceChargeSolver
-
class GenericSpaceChargeSolver : public SpaceCharge::FieldCalculator
Abstract base class for Barnes-Hut Tree nodes
Subclassed by ExaFMMt::FMMSolver, FMM3D::FMMSolver, SpaceCharge::FullSumSolver
Public Functions
-
GenericSpaceChargeSolver()
Default Constructor
-
void insertParticle(Core::Particle &particle, std::size_t ext_index)
Insert particle into the field solver
- Parameters:
particle – the particle to insert
ext_index – an external index number for the particle / numerical particle id (most likely from simion)
-
void removeParticle(std::size_t ext_index)
Removes a particle with a given particle index / particle id and its hosting leaf node from the fmm solver
- Parameters:
ext_index – the external numerical particle id
-
std::size_t getNumberOfParticles() const
Gets the number of particles in the fmm solver
-
virtual void computeChargeDistribution() = 0
-
GenericSpaceChargeSolver()
Sub Module: BTree
The BTree sub module provides an Barnes-Hut tree implementation for space charge calculation.
Tree Node Base Classes
Barnes-Hut trees are in fact tree structures which are formed by a set of nodes and connections (edges) between them. BTree::AbstractNode is an abstract base class for all tree nodes, it bundles all characteristics and methods all nodes have. BTree::GenericBaseNode bundles generic basic methods which are applicable for all concrete node types, e.g. particle insertion into the node or particle removal from the node.
-
class AbstractNode
Abstract base class for Barnes-Hut Tree nodes
Subclassed by BTree::GenericBaseNode< Node >, BTree::GenericBaseNode< ParallelNode >, BTree::GenericBaseNode< NodType >
Public Types
Public Functions
-
AbstractNode(Core::Vector min, Core::Vector max)
Constructs a tree node
- Parameters:
min – the lower corner of the node (spatial xlo,ylo,zlo corner)
max – the upper corner of the node (spatial xhi,yhi,zhi corner)
parent – the parent node, the new node will be a subnode of that node (can be nullptr for root nodes)
-
virtual ~AbstractNode() = default
-
AbstractNode(const AbstractNode &that) = default
-
std::size_t getNumberOfParticles() const
Gets the number of particles in the node including the suboctant nodes and thus all particles in the spatial extend of the node
-
BTree::TreeParticle *getParticle() const
Gets a pointer to the particle in the node
-
Core::Vector getMax() const
Returns the “upper” corner of the node (corner with xHi, yHi, zHi coordinates)
-
Core::Vector getMin() const
Returns the “lower” corner of the node (corner with xLo, yLo, zLo coordinates)
-
double getCharge() const
Returns the total charge of the node (including the contributions of the subnodes)
-
Core::Vector getCenterOfCharge() const
Returns the geometric center of charge of the node (including the contribution of the subnodes)
-
Octant getOctant(Core::Vector location) const
Returns the sub-octant of the current node where a given location falls into
- Parameters:
location – a location to get the sub-octant for
- Returns:
the sub octant in which given location falls into
-
virtual void initAsRoot() = 0
-
virtual bool isRoot() const = 0
-
virtual void updateParents() = 0
-
virtual void updateSelf() = 0
-
virtual void removeMyselfFromTree() = 0
-
virtual void insertParticle(BTree::TreeParticle *particle) = 0
-
virtual void computeChargeDistributionRecursive() = 0
-
virtual std::string toString() const = 0
Public Static Functions
-
static int getNumberOfNodes()
Return total number of existing tree nodes
-
static void setTheta(double newTheta)
Sets the multipole acceptance criterion (theta) for the nodes
-
static double getTheta()
Gets current value of multipole acceptance criterion (theta)
-
static Core::Vector calculateElectricField(const Core::Vector &r1, const Core::Vector &r2, double charge2)
Computes the electric field on a test charge located at r1 from a charge located at r2
- Parameters:
r1 – the position of the small test charge (in m)
r2 – the position of the charge “charge2” (in m)
charge2 – the charge of “charge2” (in coulomb)
- Returns:
The electric field at the position r1
Public Static Attributes
-
static constexpr double CHARGE_EPSILON = Core::ELEMENTARY_CHARGE * 1e-3
lower boundary of possible charge in nodes,
-
AbstractNode(Core::Vector min, Core::Vector max)
-
template<class NodType>
class GenericBaseNode : public BTree::AbstractNode Templated base class for nodes in Barnes-Hut tree, which bundles generalizable methods / algorithms for concrete tree node types NodType.
This class uses the Curiously recurring template pattern (CRTP) / F-bound idiom to generalize functionality for concrete tree nodes.
- Template Parameters:
NodType – the concrete node type to generate generalizable methods for
Public Functions
-
GenericBaseNode(Core::Vector min, Core::Vector max, NodType *parent)
Basic constructor
- Parameters:
min – The lower corner of the node
max – The upper corner of the node
parent – A node which is the parent node in the tree structure of this node
-
GenericBaseNode(const GenericBaseNode &that) = delete
-
GenericBaseNode &operator=(const GenericBaseNode &that) = delete
-
~GenericBaseNode() override
Destructor
-
virtual void initAsRoot() override
Inits a node as root of a tree
-
virtual bool isRoot() const override
Returns true if the node is a root (has no parent)
-
NodType *createOctNode(Octant oct)
Creates a new sub-octant node as a child of this node in one of the sub octants of this node.
- Parameters:
oct – the location / sub-octant where the new node should be created
- Returns:
the newly created sub-octant node
-
NodType **getOctants()
Get links to the child octant nodes
- Returns:
c style array with pointers to the child octant nodes
-
virtual void removeMyselfFromTree() override
Removes this node from the tree structure
-
virtual void updateSelf() override
Updates the state of this node
-
virtual void updateParents() override
Updates the internal state of the parent nodes of this node up to the tree root
-
virtual void insertParticle(BTree::TreeParticle *particle) override
Inserts a particle into the node. If the node is already occupied, the node is subdivided into sub-nodes and the particle is inserted in the according sub-nodes.
- Parameters:
particle – the particle to insert into the node.
-
virtual void computeChargeDistributionRecursive() override
Computes the charge distribution in this node and its subnodes and updates the node and its subnodes with updates charge and center of charge values
-
virtual std::string toString() const override
Returns a string which reflects the state of the node
-
virtual void printTree(int level) const
Prints the tree with this node as root to cout
- Parameters:
level – level of the current tree node with respect to the tree root (should be 0 when called manually)
-
void writeToStream(std::ostream &filestream, void (*writeFct)(std::ostream &filestream, const NodType *node)) const
A method to export internal information to a filestream. The data transformation and formatting is done by a passed write function. The write function is recursively applied to all subnodes of this node and thus the whole subtree below this node.
- Parameters:
filestream – a filestream to write to
writeFct – a function, taking the filestream and a Core node, which extracts information from the node
-
virtual void testNodeIntegrity(int level)
Tests the node integrity of the subtree with the current node as root
- Parameters:
debug – prints some additional information to cout if true
level – level of the current tree node with respect to the tree root (should be 0 when called manually)
- Throws:
logic_error – if an inconsistent node is found
Parallelized Barnes-Hut Tree
A partly parallelized version of a Barnes-Hut tree is realized in BTree::ParallelTree, which uses BTree::ParallelNode as node class.
-
class ParallelTree : public SpaceCharge::FieldCalculator
Public Functions
-
ParallelTree(Core::Vector min, Core::Vector max)
Constructor: Constructs a new tree
- Parameters:
min – the lower spatial boundary of the tree domain
min – the upper spatial boundary of the tree domain
-
ParallelNode *getRoot() const
Get the tree root node
-
treeParticlePtrList *getParticleList() const
Get a linear particle linked list of the particles in the tree
-
std::size_t getNumberOfParticles() const
Gets the number of particles in the tree
-
std::size_t init()
Inits the internal data structures after a structural change on the tree structure and returns the total number of tree nodes.
- Returns:
the total number of nodes in this tree
-
std::vector<std::size_t> countNodesOnLevels()
Counts and returns the number of nodes on the individual tree levels and
-
virtual Core::Vector getEFieldFromSpaceCharge(Core::Particle &particle)
Computes the electric field acting on a given particle from the charged particles in this tree
- Parameters:
particle – A particle to calculate the total electric field for
- Returns:
The electric field on the particle resulting from the particles in the tree
-
void insertParticle(Core::Particle &particle, std::size_t ext_index)
Insert particle into the tree
- Parameters:
particle – the particle to insert
ext_index – an external index number for the particle / numerical particle id (most likely from simion)
-
void removeParticle(std::size_t ext_index)
Removes a particle with a given particle index / particle id and its hosting leaf node from the tree
- Parameters:
ext_index – the external numerical particle id
-
BTree::TreeParticle *getParticle(std::size_t ext_index) const
Retrieves a particle from the tree by its external index
- Parameters:
ext_index – the external particle index
- Returns:
the retrieved particle
-
void updateParticleLocation(std::size_t extIndex, Core::Vector newLocation, int *numNodesChanged)
Upates the location of a particle in this tree.
- Parameters:
extIndex – Index / ID of the Particle to modify
newLocation – Location to set for the selected particle
numNodesChanged – an integer reference to count the number of structurally changed nodes
-
std::size_t updateNodes(int ver)
Updates the internal state of the nodes in this tree. The update is performed serialized and parallelized.
- Parameters:
ver – number of nodes which have changed in terms of tree structure (0 means that the structure of the tree has not changed and the serialized data structures has not to be updated)
- Returns:
the total number of nodes in the tree
-
void printParticles() const
-
ParallelTree(Core::Vector min, Core::Vector max)
-
class ParallelNode : public BTree::GenericBaseNode<ParallelNode>
Public Functions
-
ParallelNode(Core::Vector min, Core::Vector max, ParallelNode *parent)
Constructs a tree node
- Parameters:
min – the lower corner of the node (spatial xlo,ylo,zlo corner)
max – the upper corner of the node (spatial xhi,yhi,zhi corner)
parent – the parent node, the new node will be a subnode of that node (can be nullptr for root nodes)
-
ParallelNode(const ParallelNode &that) = delete
-
ParallelNode &operator=(const ParallelNode &that) = delete
-
void serializeIntoVector(std::vector<BTree::ParallelNode*> &serializedNodes, std::size_t treeLevel, std::vector<std::size_t> &insertPositions)
Serializes the subtree with this node as root into a serialized vector of pointers to the nodes. The nodes are sorted according to their level. The current insert position on the individual tree levels are given in a second vector. The given serializedNodes vector has to be sufficiently large to hold all nodes of the sub tree and the initial insertPositions have to be at the correct positions so that nodes of the individual tree levels fit into the serialized vector without overlap
- Parameters:
serializedNodes – A vector of node pointers in which the subtree is serialized into
treeLevel – The current tree level (starting from the root)
insertPositions – A vector with the current insert positions in the serialized vector for the individual tree levels
-
std::size_t maximumRecursionDepth() const
Determines the maximum depth, in terms of tree levels, of the (sub) tree with this node as root
- Returns:
The maximum number of tree levels of the subtree with this node as root
-
void countNodesOnLevel(std::size_t level, std::vector<std::size_t> &numOfNodesOnLevels) const
Count nodes on individual tree levels in the subtree with this node as root.
- Parameters:
level – The level of this node is on the global tree
numOfNodesOnLevels – a vector, one element per tree level, to count the the nodes number into
-
ParallelNode(Core::Vector min, Core::Vector max, ParallelNode *parent)
Serial Barnes-Hut Tree
A legacy, non parallelized, simple version of a Barnes-Hut tree is BTree::Tree, which uses BTree::Node as node class. This tree version is mostly used for benchmarks or comparison purposes.
-
class Tree : public SpaceCharge::FieldCalculator
Public Functions
-
Tree(Core::Vector min, Core::Vector max)
Constructs a new tree
- Parameters:
min – the lower spatial boundary of the tree domain
max – the upper spatial boundary of the tree domain
-
treeParticlePtrList *getParticleList()
Gets a linear particle list of the particles in the tree
- Returns:
a linearized linked list of the particles in the tree
-
std::size_t getNumberOfParticles() const
Get the number of particles in the tree
- Returns:
the number of particles in the tree
-
void computeChargeDistribution()
Computes / initalizes the charge distribution in the tree: The charge in the individual tree nodes is calculated from the particles in the tree
-
virtual Core::Vector getEFieldFromSpaceCharge(Core::Particle &particle) override
Computes the electric field from the particles in the tree on a given test particle
- Parameters:
particle – a testparticle on which the electric force from the tree acts
- Returns:
the electric force on that particle
-
void insertParticle(Core::Particle &particle, size_t ext_index)
Insert an unwrapped particle into the tree
- Parameters:
particle – the particle to insert
ext_index – an external index number for the particle / numerical particle id (most likely from a SIMION simulation)
-
void removeParticle(size_t ext_index)
Removes a particle with a given particle index / particle id and its hosting leaf node from the tree
- Parameters:
ext_index – the external numerical particle index
-
BTree::TreeParticle *getParticle(size_t ext_index) const
Retrieves a particle from the tree by its external index
- Parameters:
ext_index – the external particle index
- Returns:
the retrieved particle
-
void updateParticleLocation(size_t ext_index, Core::Vector newLocation)
Updates the location of a particle in the tree (the position of particles managed by the tree should not be updated directly via the particle, this will invalidate the tree)
- Parameters:
ext_index – the external index of the particle to update
newLocation – a new location of that particle
-
void printParticles() const
Prints the particles in the tree to cout
-
Tree(Core::Vector min, Core::Vector max)
-
class Node : public BTree::GenericBaseNode<Node>
Public Functions
-
Node(Core::Vector min, Core::Vector max, Node *parent)
Constructs a tree node
- Parameters:
min – the lower corner of the node (spatial xlo,ylo,zlo corner)
max – the upper corner of the node (spatial xhi,yhi,zhi corner)
parent – the parent node, the new node will be a subnode of that node (can be nullptr for root nodes)
-
Core::Vector computeElectricFieldFromTree(Core::Particle &targetP)
Computes the electric field on a given particle from the charged particles in a tree with this node as root node
- Parameters:
targetP – a particle to calculate the total electric field for
- Returns:
the electric force on the particle resulting from the particles in the tree with this node as root
-
void testSpatialTreeIntegrity()
Tests if all tree nodes are within the spatial limits of their parent nodes
- Throws:
logic_error – if an inconsistent node is found
-
void testNodeParticleIntegrity()
Tests if the particles in the nodes of the subtree with this node as root are consistent, regarding the spatial positions.
- Throws:
logic_error – if a particle is found which is out of the spatioal bounds of its containing node
-
bool isNodeInSubtree(const Node *nodeToFind, bool debug) const
Checks if a tree node is in a subtree with this node as root
- Parameters:
nodeToFind – pointer to the node to find in the subtree
debug – prints information about the found node to cout if true
- Returns:
true if the given node is found in the subtree
-
bool isParticleInSubtree(const TreeParticle *particle, bool debug) const
Checks if a particle is in a subtree with this node as root
- Parameters:
particle – pointer to a particle to find in the subtree
debug – prints information about the found particle if true
- Returns:
true if the particle is found in the subtree
-
Node(Core::Vector min, Core::Vector max, Node *parent)
Sub Modules: Fast Multipole Methods (FMM)
Two submodules provide interfaces to external fast multipole method (FMM) libraries to allow fast space charge calculations with FMM.
exafmm-t Interface
Interface to exafmm-t for coulombic interaction (space charge) calculations. This modules a build with the path to exafmm-t passed via EXAFMMT_PATH variable in the cmake configuration, as described in the installation guide.
-
class FMMSolver : public SpaceCharge::GenericSpaceChargeSolver
FMM3D Interface
Interface to FMM3D for coulombic interaction (space charge) calculations. This modules a build with the path to exafmm-t passed via FMM_3D_PATH variable in the cmake configuration, as described in the installation guide
-
class FMMSolver : public SpaceCharge::GenericSpaceChargeSolver