Ejemplo n.º 1
0
        private void GetNeighbors_3OtherPrimaryParticlesAre2DClose_1isTooFarAway()
        {
            var r               = 5;
            var pos             = new Vector3(0, 0, 100);
            var primaryParticle = new PrimaryParticle(0, pos, r);

            var handler = new BallisticSingleParticleDepositionHandler();

            var pos2 = new Vector3(0, 3, 10);
            var pos3 = new Vector3(3, -3, 10);
            var pos4 = new Vector3(-3, -3, 10);
            var pos5 = new Vector3(-30, -30, 10);
            var pp2  = new PrimaryParticle(1, pos2, r);
            var pp3  = new PrimaryParticle(2, pos3, r);
            var pp4  = new PrimaryParticle(3, pos4, r);
            var pp5  = new PrimaryParticle(4, pos5, r);

            var particles = new List <PrimaryParticle>()
            {
                pp2, pp3, pp4, pp5
            };
            var neighborsList = _neighborslistFactory.Build2DNeighborslist(particles);
            var maxRadius     = particles.GetMaxRadius();
            var searchRadius  = (primaryParticle.Radius + maxRadius) * _config.Delta;
            var neighbors     = neighborsList.GetPrimaryParticlesWithinRadius(primaryParticle.Position, searchRadius);

            //var neighbors = handler.GetNeighbors(primaryParticle, neighborsList, maxRadius);

            Assert.Equal(3, neighbors.Count());
            foreach (var neighbor in neighbors)
            {
                Assert.NotEqual(pos5, neighbor.Position);
            }
        }
Ejemplo n.º 2
0
        private void ComputeCorrectMinDepositionDistance_CollisionWithPrimaryParticleTwoNeighbors()
        {
            var r               = 1.0;
            var pos             = new Vector3(0, 0, 100);
            var primaryParticle = new PrimaryParticle(0, pos, r);

            var handler = new BallisticSingleParticleDepositionHandler();

            var pos2           = new Vector3(1, 0, 10);
            var pp2            = new PrimaryParticle(1, pos2, r);
            var pos3           = new Vector3(1, 0, 5);
            var pp3            = new PrimaryParticle(1, pos3, r);
            var otherParticles = new List <PrimaryParticle>()
            {
                pp2, pp3
            };

            var neighborsList = _neighborslistFactory.Build2DNeighborslist(otherParticles);

            var dist = handler.GetDepositionDistance(primaryParticle, otherParticles, neighborsList, otherParticles.GetMaxRadius(), _config.Delta);

            var shouldBeDistance = 90 - Math.Sqrt(3);

            Assert.Equal(shouldBeDistance, dist);
        }
        private static Aggregate GetExampleAggregate()
        {
            var radius   = 1.0;
            var p11      = new PrimaryParticle(0, new Vector3(0, 0, 100), radius);
            var p12      = new PrimaryParticle(1, new Vector3(2 * radius, 0, 100), radius);
            var p13      = new PrimaryParticle(2, new Vector3(0, 2 * radius, 100), radius);
            var p14      = new PrimaryParticle(3, new Vector3(2 * radius, 2 * radius, 100), radius);
            var cluster1 = new Cluster(0, new List <PrimaryParticle>()
            {
                p11, p12, p13, p14
            });

            var p21      = new PrimaryParticle(0, new Vector3(0, 0, 100 - 2 * radius), radius);
            var p22      = new PrimaryParticle(1, new Vector3(2 * radius, 0, 100 - 2 * radius), radius);
            var p23      = new PrimaryParticle(2, new Vector3(0, 2 * radius, 100 - 2 * radius), radius);
            var p24      = new PrimaryParticle(3, new Vector3(2 * radius, 2 * radius, 100 - 2 * radius), radius);
            var cluster2 = new Cluster(0, new List <PrimaryParticle>()
            {
                p21, p22, p23, p24
            });

            var aggregate = new Aggregate(new List <Cluster>()
            {
                cluster1, cluster2
            });

            return(aggregate);
        }
Ejemplo n.º 4
0
        public void TrySetClusterTest()
        {
            var pp1      = new PrimaryParticle(1, new Vector3(0, 0, 0), 5);
            var pp2      = new PrimaryParticle(2, new Vector3(0, 0, 10), 5);
            var cca      = new ClusterClusterAggregationFactory(_monoPSD, _config, _logger, _neighborslistFactory, _seed);
            var cluster1 = new Cluster(1, new List <PrimaryParticle>()
            {
                pp1, pp2
            });
            var depositedCluster = new List <Cluster>
            {
                cluster1
            };
            var neighborslist = _neighborslistFactory.Build3DNeighborslist(cluster1.PrimaryParticles);

            var pp3      = new PrimaryParticle(3, new Vector3(0, 0, 30), 5);
            var pp4      = new PrimaryParticle(4, new Vector3(0, 0, 20), 5);
            var cluster2 = new Cluster(1, new List <PrimaryParticle>()
            {
                pp3, pp4
            });
            var position = new Vector3(0, 0, 25.02);

            cluster2.MoveTo(position);
            var set = cca.IsClusterPositionValid(cluster2, neighborslist, depositedCluster);

            Assert.True(set);

            var position2 = new Vector3(0, 0, 24);

            cluster2.MoveTo(position2);
            var set2 = cca.IsClusterPositionValid(cluster2, neighborslist, depositedCluster);

            Assert.False(set2);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Since there is a nearby primary particle, check if the position is valid:
 /// (1) there is at least 1 contact with other primary particles
 /// (2) there are no overlaps.
 /// </summary>
 /// <param name="particle"></param>
 /// <param name="primaryParticles"></param>
 /// <param name="config"></param>
 /// <param name="neighbors"></param>
 /// <returns></returns>
 private static bool IsAnyNeighborPositionValid(
     PrimaryParticle particle,
     Vector3 setToPosition,
     IAggregateFormationConfig config,
     IEnumerable <Tuple <PrimaryParticle, double> > neighborsWithDistance)
 {
     var(isInContact, hasNoOverlap) = ParticleFormationUtil.IsAnyNeighborInContactOrOverlapping(particle, setToPosition, config, neighborsWithDistance);
     return(isInContact && hasNoOverlap);
 }
 private void CheckXDimension(PrimaryParticle primaryParticle, ISimulationBox simulationBox)
 {
     if (primaryParticle.Position.X > simulationBox.XDim.Upper)
     {
         primaryParticle.MoveBy(new Vector3(-1 * simulationBox.XDim.Width, 0, 0));
     }
     if (primaryParticle.Position.X < simulationBox.XDim.Lower)
     {
         primaryParticle.MoveBy(new Vector3(simulationBox.XDim.Width, 0, 0));
     }
 }
        private static IEnumerable <PrimaryParticle> GetDepositedParticlesFarAway()
        {
            var radius = 1.0;
            var pos2   = new Vector3(30, 30, 1);
            var pp2    = new PrimaryParticle(1, pos2, radius);

            return(new List <PrimaryParticle>()
            {
                pp2
            });
        }
 private void CheckYDimension(PrimaryParticle primaryParticle, ISimulationBox simulationBox)
 {
     if (primaryParticle.Position.Y > simulationBox.YDim.Upper)
     {
         primaryParticle.MoveBy(new Vector3(0, -1 * simulationBox.YDim.Width, 0));
     }
     if (primaryParticle.Position.Y < simulationBox.YDim.Lower)
     {
         primaryParticle.MoveBy(new Vector3(0, simulationBox.YDim.Width, 0));
     }
 }
Ejemplo n.º 9
0
        private void DistanceToCenterLine_CorrectDistanceComputed()
        {
            var r               = 5;
            var pos             = new Vector3(0, 0, 100);
            var primaryParticle = new PrimaryParticle(0, pos, r);

            var neighborPosposition = new[] { 1.0, 1.0 };

            var dist = primaryParticle.GetDistanceToVerticalAxis(neighborPosposition);

            Assert.Equal(Math.Sqrt(2), dist);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Search in a defined radius around the primary particles if there are any more primary particles.
        /// </summary>
        /// <param name="primaryParticle">Primary particle that will be positioned</param>
        /// <param name="randomPosition">The random position where the primary particle might be positioned</param>
        /// <param name="otherPrimaryParticles">All primary particles that are already deposited (and remain fixed)</param>
        /// <param name="config"></param>
        /// <returns></returns>
        public static List <NodeDistance <KDTreeNode <double> > > GetPossibleNeighbors(
            PrimaryParticle primaryParticle,
            Vector3 randomPosition,
            KDTree <double> tree,
            IEnumerable <PrimaryParticle> otherPrimaryParticles,
            IAggregateFormationConfig config)
        {
            var searchRadius = (primaryParticle.Radius + otherPrimaryParticles.GetMaxRadius()) * config.Delta;
            var neighbors    = tree.Nearest(randomPosition.ToArray(),
                                            radius: searchRadius);

            return(neighbors);
        }
        private static void AddParticleToAggregates(List <Aggregate> aggregates, string line, Dictionary <string, int> map)
        {
            var primaryParticleId = Convert.ToInt32(line[map["id"]]);
            var aggregateId       = Convert.ToInt32(line[map["aggregate"]]);
            var clusterId         = Convert.ToInt32(line[map["cluster"]]);
            var x      = Convert.ToDouble(line[map["x"]], CultureInfo.InvariantCulture);
            var y      = Convert.ToDouble(line[map["y"]], CultureInfo.InvariantCulture);
            var z      = Convert.ToDouble(line[map["z"]], CultureInfo.InvariantCulture);
            var radius = Convert.ToDouble(line[map["Radius"]], CultureInfo.InvariantCulture);

            var position = new Vector3(x, y, z);
            var pp       = new PrimaryParticle(primaryParticleId, position, radius);
            var clus     = GetCluster(aggregates, aggregateId, clusterId);

            clus.PrimaryParticles.Add(pp);
        }
Ejemplo n.º 12
0
        private void ComputeCorrectDepositionDistance_CollisionWithParticle()
        {
            var r               = 1.0;
            var pos             = new Vector3(0, 0, 100);
            var primaryParticle = new PrimaryParticle(0, pos, r);

            var neighbor = new PrimaryParticle(1, new Vector3(1, 0, 10), 1.0);

            var dist = BallisticSingleParticleDepositionHandler.Get1DDistanceToNeighbor(primaryParticle, neighbor);

            // Math.Sqrt(3) results from the square of the combined radius (4) - the distance to centerline.
            // This origins from the triangle: final position pp1. position neigbor, center projection neighbor.
            var shouldBeDistance = 90 - Math.Sqrt(3);

            Assert.Equal(shouldBeDistance, dist);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// (1) Check for the specific primary particles if the position is valid: no overlap
        /// (2) Check if any other primary particle is in contact
        /// </summary>
        /// <param name="tree">neighborListTree</param>
        /// <param name="primaryParticle">primary particle of interest</param>
        /// <param name="otherPrimaryParticles">all other fixed primary particles</param>
        /// <param name="config"></param>
        /// <returns></returns>
        public (bool isInContact, bool hasNoOverlap) IsPrimaryParticlePositionValid(
            INeighborslist neighborslist,
            PrimaryParticle primaryParticle,
            IEnumerable <PrimaryParticle> otherPrimaryParticles)
        {
            //var neighbors = ParticleFormationUtil.GetPossibleNeighbors(primaryParticle, primaryParticle.Position, tree, otherPrimaryParticles, config);
            var searchRadius          = (primaryParticle.Radius + otherPrimaryParticles.GetMaxRadius()) * _config.Delta;
            var neighborsWithDistance = neighborslist.GetPrimaryParticlesAndDistanceWithinRadius(primaryParticle.Position, searchRadius);

            if (!neighborsWithDistance.Any())
            {
                return(isInContact : false, hasNoOverlap : true);
            }

            return(ParticleFormationUtil.IsAnyNeighborInContactOrOverlapping(primaryParticle, primaryParticle.Position, _config, neighborsWithDistance));
        }
Ejemplo n.º 14
0
        internal static double Get1DDistanceToNeighbor(PrimaryParticle primaryParticle, PrimaryParticle neighbor)
        {
            var distanceToCenterline = primaryParticle.GetDistanceToVerticalAxis(neighbor);
            var combinedRadius       = neighbor.Radius + primaryParticle.Radius;

            // If the neighbor is close but it won't be hit during deposition return max deposition distance
            if (distanceToCenterline > combinedRadius)
            {
                return(primaryParticle.Position.Z - primaryParticle.Radius);
            }

            var extraHeight = Math.Sqrt(Math.Pow(combinedRadius, 2) - Math.Pow(distanceToCenterline, 2));
            var distance    = primaryParticle.Position.Z - neighbor.Position.Z - extraHeight;

            return(distance);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// The second primary particle position is determined by its and the radius of the initial primary particle
        /// </summary>
        /// <param name="primaryParticles"></param>
        public void SetSecondPrimaryParticle(List <PrimaryParticle> primaryParticles)
        {
            var radius = _psd.GetRandomSize();
            // Distance of the CenterOfMass (com) of the second pp from the com
            // of the first pp
            var particle = new PrimaryParticle(0, radius);

            // Position the second primary particle directly in contact with the first
            var ppDistance = _config.Epsilon * (primaryParticles[0].Radius + particle.Radius);

            // Get any random position withon that distance
            var rndPosition = ParticleFormationUtil.GetRandomPosition(_rndGen, ppDistance);

            particle.MoveTo(rndPosition);
            primaryParticles.Add(particle);
        }
Ejemplo n.º 16
0
        public static (bool isInContact, bool hasNoOverlap) IsAnyNeighborInContactOrOverlapping(
            PrimaryParticle particle,
            Vector3 setToPosition,
            IAggregateFormationConfig config,
            IEnumerable <Tuple <PrimaryParticle, double> > neighborsWithDistance)
        {
            var isInContact  = false;
            var hasNoOverlap = true;

            foreach (var neigh in neighborsWithDistance)
            {
                var radiusParticle2 = neigh.Item1.Radius;
                var distance        = neigh.Item2;
                isInContact  = isInContact || IsInContact(distance, particle.Radius, radiusParticle2, config.Delta);
                hasNoOverlap = hasNoOverlap && HasNoOverlap(distance, particle.Radius, radiusParticle2, config.Epsilon);
            }
            return(isInContact, hasNoOverlap);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// A primary particle positon is valid if:
        /// (1) there is at least 1 contact with other primary particles
        /// (2) there are no overlaps.
        /// </summary>
        /// <param name="particle"></param>
        /// <param name="rndPosition"></param>
        /// <param name="tree"></param>
        /// <param name="primaryParticles"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public bool IsPrimaryParticlePositionValid(
            PrimaryParticle particle,
            Vector3 rndPosition,
            INeighborslist neighborslist,
            IEnumerable <PrimaryParticle> primaryParticles,
            IAggregateFormationConfig config)
        {
            // Get all neighbors within potential reach of the primary particle
            var searchRadius          = (particle.Radius + primaryParticles.GetMaxRadius()) * config.Delta;
            var neighborsWithDistance = neighborslist.GetPrimaryParticlesAndDistanceWithinRadius(rndPosition, searchRadius);

            // no neighbor: invalid position
            if (!neighborsWithDistance.Any())
            {
                return(false);
            }
            return(IsAnyNeighborPositionValid(particle, rndPosition, config, neighborsWithDistance));
        }
Ejemplo n.º 18
0
        public void IsPrimaryParticlePositionValid_CorrectDetectionTest()
        {
            var pp1 = new PrimaryParticle(1, new Vector3(), 4.5);
            var pp2 = new PrimaryParticle(2, new Vector3(4.035344, 0.969021, 7.427756), 4.0);
            var primaryParticles = new List <PrimaryParticle>()
            {
                pp1, pp2
            };

            var pp3           = new PrimaryParticle(3, 5.5);
            var com           = primaryParticles.GetCenterOfMass();
            var setPosition   = new Vector3(-11.098618, 1.316368, -6.026161) + com;
            var psd           = new MonodispersePrimaryParticleSizeDistribution(5);
            var pca           = new ParticleClusterAggregationFactory(psd, _rndGen, _config, _neighborslistFactory, _logger);
            var neighborslist = _neighborslistFactory.Build3DNeighborslist(primaryParticles);
            var check         = pca.IsPrimaryParticlePositionValid(pp3, setPosition, neighborslist, primaryParticles, _config);

            Assert.True(check);
        }
Ejemplo n.º 19
0
        public void FeasiblePositionTest()
        {
            var logger = new Mock <ILogger>().Object;
            var rndGen = new Random(_seed);

            var cca = new ClusterClusterAggregationFactory(_monoPSD, _config, _logger, _neighborslistFactory, _seed);

            var pp1 = new PrimaryParticle(1, new Vector3(0, 0, 0), 5);
            var pp2 = new PrimaryParticle(2, new Vector3(0, 0, 10), 5);

            var cluster1 = new Cluster(1, new List <PrimaryParticle>()
            {
                pp1, pp2
            });
            var depositedCluster = new List <Cluster>
            {
                cluster1
            };

            var neighborslist = _neighborslistFactory.Build3DNeighborslist(cluster1.PrimaryParticles);


            var pp3 = new PrimaryParticle(3, new Vector3(0, 0, 25), 5);
            var pp4 = new PrimaryParticle(4, new Vector3(0, 0, 19), 5);
            var pp5 = new PrimaryParticle(4, new Vector3(0, 0, 20.02), 5);

            var(anyNearby1, allFeasible1) = cca.IsPrimaryParticlePositionValid(neighborslist, pp3, depositedCluster.GetPrimaryParticles());

            Assert.False(anyNearby1);
            Assert.True(allFeasible1);

            var(anyNearby2, allFeasible2) = cca.IsPrimaryParticlePositionValid(neighborslist, pp4, depositedCluster.GetPrimaryParticles());

            Assert.True(anyNearby2);
            Assert.False(allFeasible2);

            var(anyNearby3, allFeasible3) = cca.IsPrimaryParticlePositionValid(neighborslist, pp5, depositedCluster.GetPrimaryParticles());

            Assert.True(anyNearby3);
            Assert.True(allFeasible3);
        }
        private static int GetPrimaryParticleOverlaps(PrimaryParticle primaryParticle, IParticleFilm <Aggregate> particleFilm, INeighborslist neighborslist, bool highlightPrimaryParticle)
        {
            var neighbors = neighborslist.GetPrimaryParticlesAndDistanceWithinRadius(primaryParticle.Position, primaryParticle.Radius + particleFilm.PrimaryParticles.GetMaxRadius());
            var count     = 0;

            foreach (var neigh in neighbors)
            {
                if (primaryParticle == neigh.Item1)
                {
                    continue;
                }
                if (primaryParticle.Radius + neigh.Item1.Radius - neigh.Item2 > 1e-6)
                {
                    count++;
                    if (highlightPrimaryParticle)
                    {
                        primaryParticle.Type = 2;
                    }
                }
            }
            return(count);
        }
Ejemplo n.º 21
0
        private void ComputeCorrectMinDepositionDistance_NoCollision()
        {
            var r               = 1.0;
            var pos             = new Vector3(0, 0, 100);
            var primaryParticle = new PrimaryParticle(0, pos, r);

            var handler = new BallisticSingleParticleDepositionHandler();

            var pos2           = new Vector3(5, 0, 10);
            var pp2            = new PrimaryParticle(1, pos2, r);
            var otherParticles = new List <PrimaryParticle>()
            {
                pp2
            };

            var neighborsList = _neighborslistFactory.Build2DNeighborslist(otherParticles);

            var dist = handler.GetDepositionDistance(primaryParticle, otherParticles, neighborsList, otherParticles.GetMaxRadius(), _config.Delta);

            var shouldBeDistance = primaryParticle.Position.Z - primaryParticle.Radius;

            Assert.Equal(shouldBeDistance, dist);
        }
Ejemplo n.º 22
0
        public double GetDepositionDistance(
            PrimaryParticle primaryParticle,
            IEnumerable <PrimaryParticle> depositedPrimaryParticles,
            INeighborslist neighborsList2D,
            double maxRadius,
            double delta)
        {
            var distance = primaryParticle.Position.Z - primaryParticle.Radius;

            if (!depositedPrimaryParticles.Any())
            {
                return(distance);
            }

            var searchRadius = (primaryParticle.Radius + maxRadius) * delta;
            var neighbors    = neighborsList2D.GetPrimaryParticlesWithinRadius(primaryParticle.Position, searchRadius);

            foreach (var neighbor in neighbors)
            {
                distance = Math.Min(distance, Get1DDistanceToNeighbor(primaryParticle, neighbor));
            }

            return(distance);
        }
Ejemplo n.º 23
0
        private void ComputeCorrectMinDepositionDistance_CollisionWithPrimaryParticleOnlyOneNeighbor()
        {
            var r               = 1.0;
            var pos             = new Vector3(0, 0, 100);
            var primaryParticle = new PrimaryParticle(0, pos, r);

            var handler = new BallisticSingleParticleDepositionHandler();

            var pos2           = new Vector3(1, 0, 10);
            var pp2            = new PrimaryParticle(1, pos2, r);
            var otherParticles = new List <PrimaryParticle>()
            {
                pp2
            };
            var neighborsList = _neighborslistFactory.Build2DNeighborslist(otherParticles);

            var dist = handler.GetDepositionDistance(primaryParticle, otherParticles, neighborsList, otherParticles.GetMaxRadius(), _config.Delta);

            // Math.Sqrt(3) results from the square of the combined radius (4) - the distance to centerline.
            // This origins from the triangle: final position pp1. position neigbor, center projection neighbor.
            var shouldBeDistance = 90 - Math.Sqrt(3);

            Assert.Equal(shouldBeDistance, dist);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Check if the primary particle is in contact with any other primary particle (isInContact) and if it is overlapping with any other primary particle (hasNoOverlap)
        /// </summary>
        /// <param name="particle"></param>
        /// <param name="primaryParticles"></param>
        /// <param name="config"></param>
        /// <param name="neighbors"></param>
        /// <returns></returns>
        public static (bool isInContact, bool hasNoOverlap) IsAnyNeighborInContactOrOverlapping(PrimaryParticle particle, IEnumerable <PrimaryParticle> primaryParticles, IAggregateFormationConfig config, List <NodeDistance <KDTreeNode <double> > > neighbors)
        {
            var isInContact  = false;
            var hasNoOverlap = true;

            foreach (var neigh in neighbors)
            {
                var radiusParticle2 = GetRadiusOfNodePrimaryParticle(neigh.Node.Position, primaryParticles);

                isInContact  = isInContact || IsInContact(neigh.Distance, particle.Radius, radiusParticle2, config.Delta);
                hasNoOverlap = hasNoOverlap && HasNoOverlap(neigh.Distance, particle.Radius, radiusParticle2, config.Epsilon);
            }
            return(isInContact, hasNoOverlap);
        }
 private static string GetPrimaryParticleString(PrimaryParticle particle, Cluster cluster, Aggregate agg)
 {
     return($"{particle.Id} {particle.Type} {agg.Id} {cluster.Id} {DoubleToString(particle.Position.X)} {DoubleToString(particle.Position.Y)} {DoubleToString(particle.Position.Z)} {DoubleToString(particle.Radius)}{Environment.NewLine}");
 }
 /// <summary>
 /// Nothing to do here, since particles can penetrate the wall and have no lateral movement.
 /// </summary>
 /// <param name="primaryParticle"></param>
 /// <param name="simulationBox"></param>
 public void CheckPrimaryParticle(PrimaryParticle primaryParticle, ISimulationBox simulationBox)
 {
     return;
 }
 public void CheckPrimaryParticle(PrimaryParticle primaryParticle, ISimulationBox simulationBox)
 {
     CheckXDimension(primaryParticle, simulationBox);
     CheckYDimension(primaryParticle, simulationBox);
 }