35namespace energybased {
42 template<
int _Dim,
typename ForceFunc,
bool UseForcePrime>
61 double mass(
int i)
const;
67 double force(
int i,
int d)
const;
73 template<
typename ForceFunc,
bool UseForcePrime>
146template<
int Dim,
typename ForceFunc,
bool UseForcePrime>
159 double dist = computeDeltaAndDistance<Dim>(
m_treeForce.m_nodeData[a].centerOfMass,
167 for (
int d = 0; d < Dim; d++) {
169 force * delta[d] / dist *
m_treeForce.m_nodeData[b].mass;
171 force * delta[d] / dist *
m_treeForce.m_nodeData[a].mass;
200 m_pWSPD =
new WSPD(m_numPoints);
202 m_pointData =
new PointData[m_numPoints];
205 for (
int i = 0; i < m_numPoints; i++) {
206 m_pointData[i].
mass = 1.0;
214 delete[] m_pointData;
229 return wspd().
tree();
234 return wspd().
point(i).x[d];
239 wspd().setPoint(i, d, c);
244 return m_pointData[i].mass;
249 m_pointData[i].mass = m;
254 return m_pointData[i].force[d];
259 return m_pointData[i].force_prime;
263template<
typename ForceFunc,
bool UseForcePrime>
268 if (numPoints() <= 1) {
276 bottomUpPhase(
tree().rootIndex());
281 wspd().computeWSPD(&wspdCallBack);
284 topDownPhase(
tree().rootIndex());
290 for (
int d = 0; d < Dim; d++) {
291 m_nodeData[curr].force[d] = 0.0;
292 m_nodeData[curr].force_prime = 0.0;
293 m_nodeData[curr].centerOfMass[d] = 0.0;
297 m_nodeData[curr].mass = 0.0;
300 if (
tree().numChilds(curr)) {
302 for (
int i = 0; i <
tree().numChilds(curr); i++) {
304 const int child =
tree().child(curr, i);
307 bottomUpPhase(child);
310 for (
int d = 0; d < Dim; d++) {
312 m_nodeData[curr].centerOfMass[d] +=
313 m_nodeData[child].centerOfMass[d] * m_nodeData[child].mass;
317 m_nodeData[curr].mass += m_nodeData[child].mass;
322 for (
int i = 0; i <
tree().numPoints(curr); ++i) {
323 int pointIndex =
tree().point(curr, i);
325 for (
int d = 0; d < Dim; d++) {
326 m_nodeData[curr].centerOfMass[d] += position(pointIndex, d) * mass(pointIndex);
329 m_nodeData[curr].mass += mass(pointIndex);
333 for (
int d = 0; d < Dim; d++) {
334 m_nodeData[curr].centerOfMass[d] /= m_nodeData[curr].mass;
341 if (
tree().numChilds(curr)) {
343 for (
int i = 0; i <
tree().numChilds(curr); i++) {
345 const int child =
tree().child(curr, i);
348 for (
int d = 0; d < Dim; d++) {
350 m_nodeData[child].force[d] += m_nodeData[curr].force[d];
353 m_nodeData[child].force_prime += m_nodeData[curr].force_prime;
361 for (
int i = 0; i <
tree().numPoints(curr); ++i) {
363 int pointIndex =
tree().point(curr, i);
366 for (
int d = 0; d < Dim; d++) {
368 m_pointData[pointIndex].force[d] = m_nodeData[curr].force[d] * mass(pointIndex);
371 m_pointData[pointIndex].force_prime = m_nodeData[curr].force_prime * mass(pointIndex);
378 for (
int i = 0; i < m_numPoints; i++) {
379 for (
int d = 0; d < Dim; d++) {
380 m_pointData[i].force[d] = 0.0;
382 m_pointData[i].force_prime = 0.0;
void setMass(int i, double m)
sets the mass of the i-th point
void bottomUpPhase(int curr)
internal function for computing the mass and center of mass of quadtree nodes
virtual ~DTreeForce()
destructor
const WSPD & wspd() const
returns a const ref to the wspd
void deallocate()
internal for allocating mem
void topDownPhase(int curr)
internal function for accumulating forces in the leaves
const Tree & tree() const
returns a const reference to the tree
WSPD * m_pWSPD
the WSPD instance
NodeData * m_nodeData
array for the node related data
void allocate()
internal for allocating mem
void resetPointForces()
reset the point forces
int numPoints() const
returns the number of points
PointData * m_pointData
array for the point related data
void setPosition(int i, int d, double c)
sets the d-th coordinate of the i-th point
double mass(int i) const
returns the mass of the i-th point
void computeForces(ForceFunc forceFunc)
main call
void resetTreeNodes()
reset the tree nodes
int m_numPoints
the number of points
double position(int i, int d) const
returns d-th coordinate of the i-th point
double force(int i, int d) const
returns d-th coordinate of the i-th force vector
DTreeForce(int numPoints)
constructs a new WSPD (well-separated pair decomposition) for numPoints
double force_prime(int i) const
returns derivation of the d-th coordinate of the i-th force vector
int point(int i, int j) const
returns the index of the jth point covered by i's subtree.
virtual void onWellSeparatedPair(int a, int b)
called by the WSPD for well separated pair
DTreeForce< Dim > & m_treeForce
DTreeWSPDCallback(DTreeForce< Dim > &treeForce, ForceFunc forceFunc)
const Tree & tree() const
returns the corresponding Dtree
DTree< IntType, Dim > Tree
void setSeparationFactor(double s)
sets the parameter s of the WSPD (default is 1.0)
The namespace for all OGDF objects.
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
double force_prime
the first derivation of the distance based force function
double centerOfMass[Dim]
center of mass of the subtree
double force[Dim]
the force
double mass
mass of this node
double force[Dim]
the force
double mass
mass of this point