/// <summary> /// Position the next cluster depending on the already positioned cluster. /// </summary> private bool PositionNextCluster(Cluster nextCluster, List <Cluster> depositedCluster, int count, Random rndGen) { // Compute the distance of the center of mass (COM) of next cluster to the // COM of the already depositioned cluster based on the equation of the CCA var distance = GetDistanceFromCOMForNextCluster(nextCluster, depositedCluster); MoveClusterToCOM(depositedCluster); // build the neigborlist to speed up the search for the correct position var neighborslist = _neighborslistFactory.Build3DNeighborslist(depositedCluster); var isValid = false; while (!isValid) { isValid = IsRandomPositionValid(nextCluster, depositedCluster, rndGen, distance, neighborslist); // With the current configuration (primary particle sizes) no suitable position of the cluster is found // therefore, a restart is invoked. if (count > _config.MaxAttemptsPerAggregate) { _logger.Debug("Resetting aggregate generation. Time limit exceeded."); return(false); } count++; } // suitable position, add cluster to the existing cluster. depositedCluster.Add(nextCluster); return(true); }
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 double ComputePorosityInLimits <T>(IParticleFilm <T> particleFilm, double[] verticalLimits, double[] horizontalLimits, int numberOfLocations) { var poreHits = 0; var neighborsList = _neighborslistFactory.Build3DNeighborslist(particleFilm.PrimaryParticles); var maxRadius = particleFilm.PrimaryParticles.GetMaxRadius(); for (var i = 0; i < numberOfLocations; i++) { poreHits += Convert.ToInt32(IsRandomLocationInPore(verticalLimits, horizontalLimits, neighborsList, maxRadius)); } return(poreHits / Convert.ToDouble(numberOfLocations, CultureInfo.InvariantCulture)); }
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); }
/// <summary> /// The processing is decoupled from the building method to allow for restarting the building /// if it takes too long. /// This can happen mostly for polydisperse primary particle size distributions when the unsuitable sizes were /// selected for the fist few primary particles. Since the distance from COM for the next primary particle only depends /// on the mean primary particle size, this distance can be infeasible for the cluster. In that case the whole cluster formation is restarted. /// </summary> public Cluster Procedure(int size) { var count = 0; var primaryParticles = new List <PrimaryParticle>(); SetFirstPrimaryParticle(primaryParticles); SetSecondPrimaryParticle(primaryParticles); // the neighborslist speeds up the search var neighborslist = _neighborslistFactory.Build3DNeighborslist(primaryParticles); while (primaryParticles.Count < size) { if (!AddNextPrimaryParticle(primaryParticles, count, neighborslist)) { return(null); } } return(new Cluster(0, primaryParticles)); }