/// <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); }
public ISizeDistribution <int> Build(Random rndGen, IAggregateFormationConfig config) { switch (config.AggregateSizeDistributionType) { case SizeDistributionType.DissDefault: default: return(DefaultConfigurationBuilder.GetAggreateSizeDistribution(rndGen, config)); } }
private static string GetParticleSizeDistributionString(IAggregateFormationConfig config) { var psdString = "FSP Default"; if (!config.UseDefaultGenerationMethods) { psdString = config.PrimaryParticleSizeDistributionType.ToString(); } return(psdString); }
private static string GetAggregateSizeDistributionString(IAggregateFormationConfig config) { var asdString = "FSP Default"; if (!config.UseDefaultGenerationMethods) { asdString = config.AggregateSizeDistributionType.ToString(); } return(asdString); }
private static string GetAggregateFormationMethodString(IAggregateFormationConfig config) { var aggregateFormationFactoryString = "Cluster Cluster Aggregation"; if (!config.UseDefaultGenerationMethods) { aggregateFormationFactoryString = config.AggregateFormationType.ToString(); } return(aggregateFormationFactoryString); }
public void Export( List <Aggregate> aggregates, IAggregateFormationConfig config, string filename, FileFormat fileFormat) { Export(aggregates, config, filename, fileFormat, true); }
public TabulatedAggregateSizeDistribution(IFileSizeDistribution <int> tabulatedSizeDistribution, Random rndGen, IAggregateFormationConfig config, bool integrate = true) { _rndGen = rndGen; _config = config; _tabulatedSizeDistribution = tabulatedSizeDistribution; if (integrate) { IntegrateProbabilities(); } CalcMean(); }
public ParticleClusterAggregationFactory( ISizeDistribution <double> psd, Random rndGen, IAggregateFormationConfig config, INeighborslistFactory neighborslistFactory, ILogger logger) { _psd = psd; _rndGen = rndGen; _config = config; _logger = logger; _neighborslistFactory = neighborslistFactory; }
public ClusterClusterAggregationFactory( ISizeDistribution <double> primaryParticleSizeDistribution, IAggregateFormationConfig config, ILogger logger, INeighborslistFactory neighborslistFactory, int seed = -1) { _psd = primaryParticleSizeDistribution; _config = config; _logger = logger; _seed = seed; _neighborslistFactory = neighborslistFactory; }
/// <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); }
public AggregateFormationSimulationRunner( IAggregateSizeDistributionFactory aggregateSizeDistributionFactory, IPrimaryParticleSizeDistributionFactory primaryParticleSizeDistributionFactory, IAggregateFormationFactory aggregateFormationFactory, INeighborslistFactory neighborslistFactory, IAggregateFormationConfig aggregateFormationConfig, ILogger logger) { _aggregateFormationConfig = aggregateFormationConfig ?? throw new ArgumentException(nameof(aggregateFormationConfig)); _logger = logger ?? throw new ArgumentException(nameof(logger)); _aggregateFormationService = new AggregateFormationService(aggregateSizeDistributionFactory, primaryParticleSizeDistributionFactory, aggregateFormationFactory, neighborslistFactory, _aggregateFormationConfig, logger); Progress = new Progress <ProgressReportModel>(); _cts = new CancellationTokenSource(); }
public ISizeDistribution <double> Build(Random rndGen, IAggregateFormationConfig config) { switch (config.PrimaryParticleSizeDistributionType) { case SizeDistributionType.Monodisperse: return(new MonodispersePrimaryParticleSizeDistribution(config.ModalRadius)); case SizeDistributionType.LogNormal: return(new LogNormalSizeDistribution(rndGen, config)); case SizeDistributionType.DissDefault: default: return(DefaultConfigurationBuilder.GetPrimaryParticleSizeDistribution(rndGen, config)); } }
public TabulatedPrimaryParticleSizeDistribution( XMLSizeDistribution <double> tabulatedSizeDistribution, Random rndGen, IAggregateFormationConfig config, bool integrate = true) { _rndGen = rndGen; _tabulatedSizeDistribution = tabulatedSizeDistribution; _config = config; if (integrate) { IntegrateProbabilities(); } CalcMean(); }
public LogNormalSizeDistribution(Random rndGen, IAggregateFormationConfig config) { _rndGen = rndGen; _config = config; _logNormal = new LogNormal(Mu, _config.StdPPRadius, rndGen); ComputeMeans(); Mean = config.RadiusMeanCalculationMethod switch { MeanMethod.Arithmetic => _arithmeticMean, MeanMethod.Sauter => _sauterMean, MeanMethod.Geometric => _geometricMean, _ => _geometricMean, }; }
internal AggregateFormationService ( ISizeDistribution <int> aggregateSizeDistribution, ISizeDistribution <double> primaryParticleSizeDistribution, IAggregateFormationConfig config, IParticleFactory <Aggregate> particleFactory, ILogger logger, int seed = -1 ) { _seed = seed; _aggregateSizeDistribution = aggregateSizeDistribution; _primaryParticleSizeDistribution = primaryParticleSizeDistribution; _config = config; _logger = logger; _particleFactory = particleFactory; }
/// <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)); }
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); }
public AggregateFormationService( IAggregateSizeDistributionFactory aggregateSizeDistributionFactory, IPrimaryParticleSizeDistributionFactory primaryParticleSizeDistributionFactory, IAggregateFormationFactory aggregateFormationFactory, INeighborslistFactory neighborslistFactory, IAggregateFormationConfig config, ILogger logger) { _aggregateSizeDistributionFactory = aggregateSizeDistributionFactory ?? throw new ArgumentException(nameof(aggregateSizeDistributionFactory)); _primaryParticleSizeDistributionFactory = primaryParticleSizeDistributionFactory ?? throw new ArgumentException(nameof(primaryParticleSizeDistributionFactory)); _aggregateFormationFactory = aggregateFormationFactory ?? throw new ArgumentException(nameof(aggregateFormationFactory)); _neighborslistFactory = neighborslistFactory ?? throw new ArgumentException(nameof(neighborslistFactory)); _config = config ?? throw new ArgumentException(nameof(config)); _logger = logger ?? throw new ArgumentException(nameof(logger)); var rndGen = new Random(); _aggregateSizeDistribution = aggregateSizeDistributionFactory.Build(rndGen, config); _primaryParticleSizeDistribution = primaryParticleSizeDistributionFactory.Build(rndGen, config); _particleFactory = _aggregateFormationFactory.Build(_primaryParticleSizeDistribution, _neighborslistFactory, _config, _logger); }
public FullSimulationRunner( IAggregateFormationConfig aggregateFormationConfig, SimulationMonitor simulationMonitor, IAggregateSizeDistributionFactory aggregateSizeDistributionFactory, IPrimaryParticleSizeDistributionFactory primaryParticleSizeDistributionFactory, IAggregateFormationFactory aggregateFormationFactory, INeighborslistFactory neighborslistFactory, IFilmFormationConfig filmFormationConfig, ILogger logger) { _filmFormationConfig = filmFormationConfig; _progress = new Progress <ProgressReportModel>(); _filmFormationService = new FilmFormationService(filmFormationConfig); _cts = new CancellationTokenSource(); _aggregateFormationConfig = aggregateFormationConfig ?? throw new ArgumentException(nameof(aggregateFormationConfig)); _aggregateSizeDistributionFactory = aggregateSizeDistributionFactory; _primaryParticleSizeDistributionFactory = primaryParticleSizeDistributionFactory; _aggregateFormationFactory = aggregateFormationFactory; _neighborslistFactory = neighborslistFactory; _logger = logger ?? throw new ArgumentException(nameof(logger)); _aggregateFormationService = new AggregateFormationService(_aggregateSizeDistributionFactory, _primaryParticleSizeDistributionFactory, _aggregateFormationFactory, _neighborslistFactory, _aggregateFormationConfig, logger); }
public void Export( List <Aggregate> aggregates, IAggregateFormationConfig config, string filename, FileFormat fileFormat, bool doUseSI) { var output = AggregateOutputMapper.MapToAggregateOutput(aggregates, config, doUseSI); switch (fileFormat) { case FileFormat.Json: _jsonSerializer.Serialize(output, filename); break; case FileFormat.Xml: _xmlSerializer.Serialize(output, filename); break; default: return; } }
public IParticleFactory <Aggregate> Build(ISizeDistribution <double> psd, INeighborslistFactory neighborslistFactory, IAggregateFormationConfig config, ILogger logger) { switch (config.AggregateFormationType) { case AggregateFormationType.ClusterClusterAggregation: default: return(new ClusterClusterAggregationFactory(psd, config, logger, neighborslistFactory, config.RandomGeneratorSeed)); } }
public static ISizeDistribution <int> GetAggreateSizeDistribution(Random rndGen, IAggregateFormationConfig config) { var resources = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..\\..\\..\\..\\ANPaX.Simulation.AggregateFormation\\Resources\\")); var fileASD = resources + "FSP_AggregateSizeDistribution.xml"; var distASD = XMLSizeDistributionBuilder <int> .Read(fileASD); var asd = new TabulatedAggregateSizeDistribution(distASD, rndGen, config, integrate: true); return(asd); }
public static ISizeDistribution <double> GetPrimaryParticleSizeDistribution(Random rndGen, IAggregateFormationConfig config) { var resources = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..\\..\\..\\..\\ANPaX.Simulation.AggregateFormation\\Resources\\")); var filePSD = resources + "FSP_PrimaryParticleSizeDistribution.xml"; var dist = XMLSizeDistributionBuilder <double> .Read(filePSD); var psd = new TabulatedPrimaryParticleSizeDistribution(dist, rndGen, config, integrate: true); return(psd); }
/// <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); }
public static AggregateOutput MapToAggregateOutput(List <Aggregate> aggregates, IAggregateFormationConfig config, bool convertToSI) { var units = "nano"; if (convertToSI) { UnitConversionHelper.ConvertDistanceToMeter(aggregates); units = "SI"; } var output = new AggregateOutput(aggregates) { AggregateFormationMethod = GetAggregateFormationMethodString(config), ParticleSizeDistribution = GetParticleSizeDistributionString(config), AggregateSizeDistribution = GetAggregateSizeDistributionString(config), ClusterSize = config.ClusterSize, Units = units }; return(output); }
public static AggregateOutput MapToAggregateOutput(List <Aggregate> aggregates, IAggregateFormationConfig config) { return(MapToAggregateOutput(aggregates, config, true)); }