示例#1
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);
 }
 public ISizeDistribution <int> Build(Random rndGen, IAggregateFormationConfig config)
 {
     switch (config.AggregateSizeDistributionType)
     {
     case SizeDistributionType.DissDefault:
     default:
         return(DefaultConfigurationBuilder.GetAggreateSizeDistribution(rndGen, config));
     }
 }
示例#3
0
        private static string GetParticleSizeDistributionString(IAggregateFormationConfig config)
        {
            var psdString = "FSP Default";

            if (!config.UseDefaultGenerationMethods)
            {
                psdString = config.PrimaryParticleSizeDistributionType.ToString();
            }

            return(psdString);
        }
示例#4
0
        private static string GetAggregateSizeDistributionString(IAggregateFormationConfig config)
        {
            var asdString = "FSP Default";

            if (!config.UseDefaultGenerationMethods)
            {
                asdString = config.AggregateSizeDistributionType.ToString();
            }

            return(asdString);
        }
示例#5
0
        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();
        }
示例#8
0
 public ParticleClusterAggregationFactory(
     ISizeDistribution <double> psd,
     Random rndGen,
     IAggregateFormationConfig config,
     INeighborslistFactory neighborslistFactory,
     ILogger logger)
 {
     _psd    = psd;
     _rndGen = rndGen;
     _config = config;
     _logger = logger;
     _neighborslistFactory = neighborslistFactory;
 }
示例#9
0
 public ClusterClusterAggregationFactory(
     ISizeDistribution <double> primaryParticleSizeDistribution,
     IAggregateFormationConfig config,
     ILogger logger,
     INeighborslistFactory neighborslistFactory,
     int seed = -1)
 {
     _psd    = primaryParticleSizeDistribution;
     _config = config;
     _logger = logger;
     _seed   = seed;
     _neighborslistFactory = neighborslistFactory;
 }
示例#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);
        }
 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();
 }
示例#12
0
        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));
            }
        }
示例#13
0
        public TabulatedPrimaryParticleSizeDistribution(
            XMLSizeDistribution <double> tabulatedSizeDistribution,
            Random rndGen,
            IAggregateFormationConfig config,
            bool integrate = true)
        {
            _rndGen = rndGen;
            _tabulatedSizeDistribution = tabulatedSizeDistribution;
            _config = config;

            if (integrate)
            {
                IntegrateProbabilities();
            }
            CalcMean();
        }
示例#14
0
        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,
            };
        }
示例#15
0
 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;
 }
示例#16
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));
        }
示例#17
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);
        }
示例#18
0
        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);
        }
示例#19
0
 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);
        }
示例#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);
        }
示例#25
0
        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);
        }
示例#26
0
 public static AggregateOutput MapToAggregateOutput(List <Aggregate> aggregates, IAggregateFormationConfig config)
 {
     return(MapToAggregateOutput(aggregates, config, true));
 }