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); }
public void DepositAggregate(Aggregate aggregate, IEnumerable <PrimaryParticle> depositedPrimaryParticles, INeighborslist neighborslist, double maxRadius, double delta) { var distancesTasks = new List <Task <double> >(); var primaryParticles = aggregate.Cluster.SelectMany(c => c.PrimaryParticles); var distance = aggregate.Cluster.SelectMany(c => c.PrimaryParticles).Select(p => p.Position.Z - p.Radius).Min(); var tasks = new List <Task <double> >(); if (depositedPrimaryParticles.Any()) { var distances = new List <double>(); foreach (var primaryParticle in primaryParticles) { distances.Add(_singleParticleDepositionHandler.GetDepositionDistance(primaryParticle, depositedPrimaryParticles, neighborslist, maxRadius, delta)); } distance = distances.Min(); } aggregate.MoveBy(new Vector3(0, 0, -1 * distance)); }
/// <summary> /// The position of the third (and follwing) primary particle is determined by the PCA: /// The radius determined by the geometrical properties is computed and the /// primary particle is positioned in that distance to the existing ones. /// If that primary particle is in contact with another one but not /// overlapping with any other, it may reside there. /// </summary> /// <param name="primaryParticles"></param> /// <param name="count"></param> /// <returns></returns> public bool AddNextPrimaryParticle(List <PrimaryParticle> primaryParticles, int count, INeighborslist neighborslist) { var com = primaryParticles.GetCenterOfMass(); // compute the distance for the next primary particle to fulfill fractal dimension var ppDistance = GetNextPrimaryParticleDistance(primaryParticles); // get a new primary particle without any position yet. var particle = InitializeNewPrimaryParticle(_psd.GetRandomSize()); var found = false; var rndPosition = new Vector3(); while (!found) { // get a new random position on the sphere of allowed positions rndPosition = ParticleFormationUtil.GetRandomPosition(_rndGen, ppDistance) + com; // check if that position is valid found = IsPrimaryParticlePositionValid(particle, rndPosition, neighborslist, primaryParticles, _config); if (count > _config.MaxAttemptsPerCluster) { _logger.Debug("Resetting cluster generation. Time limit exceeded."); return(false); } count++; } particle.MoveTo(rndPosition); primaryParticles.Add(particle); neighborslist.AddParticlesToNeighborsList(particle); return(true); }
public async Task DepositAggregate_Async(Aggregate aggregate, IEnumerable <PrimaryParticle> depositedPrimaryParticles, INeighborslist neighborslist, double maxRadius, int maxCPU, double delta, CancellationToken ct) { var distancesTasks = new List <Task <double> >(); var primaryParticles = aggregate.Cluster.SelectMany(c => c.PrimaryParticles); var distance = aggregate.Cluster.SelectMany(c => c.PrimaryParticles).Select(p => p.Position.Z - p.Radius).Min(); var tasks = new List <Task <double> >(); if (depositedPrimaryParticles.Any()) { foreach (var primaryParticle in primaryParticles) { tasks.Add(Task.Run(() => _singleParticleDepositionHandler.GetDepositionDistance(primaryParticle, depositedPrimaryParticles, neighborslist, maxRadius, delta))); } var distances = await Task.WhenAll(tasks); //var distances = new List<double>(); //foreach (var primaryParticle in primaryParticles) //{ // distances.Add(_singleParticleDepositionHandler.GetDepositionDistance(primaryParticle, depositedPrimaryParticles, neighborslist, maxRadius)); //} distance = distances.Min(); } aggregate.MoveBy(new Vector3(0, 0, -1 * distance)); }