示例#1
0
 internal void ComputeForces()
 {
     foreach (var u in particles[0])
     {
         foreach (var v in particles[0])
         {
             if (u != v)
             {
                 u.force += MultipoleCoefficients.Force(u.point, v.point);
             }
         }
     }
 }
示例#2
0
 /// <summary>
 /// Compute forces between particles using multipole approximations.
 /// </summary>
 /// <param name="precision"></param>
 public void ComputeForces(int precision)
 {
     root.computeMultipoleCoefficients(precision);
     foreach (var l in leaves)
     {
         l.ComputeForces();
         List <KdNode> stack = new List <KdNode>();
         stack.Add(root);
         while (stack.Count > 0)
         {
             KdNode v = stack.Last();
             stack.RemoveAt(stack.Count - 1);
             if (!l.intersects(v))
             {
                 foreach (var p in l.particles[0])
                 {
                     p.force -= v.multipoleCoefficients.ApproximateForce(p.point);
                 }
             }
             else
             {
                 var leaf = v as LeafKdNode;
                 if (leaf != null)
                 {
                     foreach (var p in l.particles[0])
                     {
                         foreach (var q in leaf.particles[0])
                         {
                             if (p != q)
                             {
                                 p.force += MultipoleCoefficients.Force(p.point, q.point);
                             }
                         }
                     }
                 }
                 else
                 {
                     var n = v as InternalKdNode;
                     stack.Add(n.leftChild);
                     stack.Add(n.rightChild);
                 }
             }
         }
     }
 }
示例#3
0
        void ComputeRepulsiveForces(FiNode[] vs)
        {
            int n = vs.Length;

            if (n > 16 && settings.ApproximateRepulsion)
            {
                var ps = new KDTree.Particle[vs.Length];
                // before calculating forces we perturb each center by a small vector in a unique
                // but deterministic direction (by walking around a circle in n steps) - this allows
                // the KD-tree to decompose even when some nodes are at exactly the same position
                double angle = 0, angleDelta = 2.0 * Math.PI / n;
                for (int i = 0; i < n; ++i)
                {
                    ps[i]  = new KDTree.Particle(vs[i].Center + 1e-5 * new Point(Math.Cos(angle), Math.Sin(angle)));
                    angle += angleDelta;
                }
                var kdTree = new KDTree(ps, 8);
                kdTree.ComputeForces(5);
                for (int i = 0; i < vs.Length; ++i)
                {
                    AddRepulsiveForce(vs[i], ps[i].force);
                }
            }
            else
            {
                foreach (FiNode u in vs)
                {
                    var fu = new Point();
                    foreach (FiNode v in vs)
                    {
                        if (u != v)
                        {
                            fu += MultipoleCoefficients.Force(u.Center, v.Center);
                        }
                    }
                    AddRepulsiveForce(u, fu);
                }
            }
        }