PSD Class Reference

Contains a vector with radii and probabilities of a user defined particle size distribution (PSD) More...

#include <PSD.h>

Public Types

enum class  TYPE {
  CUMULATIVE_NUMBER_DISTRIBUTION , CUMULATIVE_LENGTH_DISTRIBUTION , CUMULATIVE_VOLUME_DISTRIBUTION , CUMULATIVE_AREA_DISTRIBUTION ,
  PROBABILITYDENSITY_NUMBER_DISTRIBUTION , PROBABILITYDENSITY_LENGTH_DISTRIBUTION , PROBABILITYDENSITY_AREA_DISTRIBUTION , PROBABILITYDENSITY_VOLUME_DISTRIBUTION
}
 Enum class which stores the possible types of CDFs and PDFs. Particle size distributions can be represented by different probabilities based on number of particles, length of particles, surface area of particles or volume of particles. More...
 

Public Member Functions

 PSD ()
 Constructor; sets everything to 0 or default. More...
 
 PSD (const PSD &other)
 Copy constructor with deep copy. More...
 
 ~PSD ()
 Destructor; default destructor. More...
 
PSDcopy () const
 Creates a copy on the heap and returns a pointer. More...
 
void printPSD () const
 Prints radii and probabilities of the PSD vector. More...
 
Mdouble drawSample ()
 Draw a sample radius from a CUMULATIVE_NUMBER_DISTRIBUTION. More...
 
Mdouble insertManuallyByVolume (Mdouble volume)
 Draw sample radius manually per size class and check the volumeAllowed of each size class to insert the PSD as accurate as possible. More...
 
void validateCumulativeDistribution ()
 Validates if a CDF starts with zero and adds up to unity. More...
 
void validateProbabilityDensityDistribution ()
 Validates if the integral of the PDF equals to unity. More...
 
MERCURYDPM_DEPRECATED void setPSDFromVector (std::vector< DistributionElements > psd, TYPE PSDType)
 Deprecated version of reading in PSDs from a vector. More...
 
void setPSDFromCSV (const std::string &fileName, TYPE PSDType, bool headings=false, Mdouble unitScalingFactorRadii=1.0)
 read in the PSD vector with probabilities and radii saved in a .csv file. More...
 
void setDistributionUniform (Mdouble radMin, Mdouble radMax, int numberOfBins)
 create a PSD vector for a uniform distribution. More...
 
void setDistributionNormal (Mdouble mean, Mdouble standardDeviation, int numberOfBins)
 create a PSD vector for a normal distribution. More...
 
void setDistributionLogNormal (Mdouble mean, Mdouble standardDeviation, int numberOfBins)
 create a PSD vector for a normal distribution. More...
 
void convertProbabilityDensityToCumulative ()
 Converts a PDF to a CDF by integration. More...
 
void convertCumulativeToProbabilityDensity ()
 Converts a CDF to a PDF by derivation. More...
 
void convertProbabilityDensityToProbabilityDensityNumberDistribution (TYPE PDFType)
 convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION. More...
 
void convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution ()
 convert a PROBABILITYDENSITY_NUMBER_DISTRIBUTION to a PROBABILITYDENSITY_VOLUME_DISTRIBUTION. More...
 
void convertCumulativeToCumulativeNumberDistribution (TYPE CDFType)
 convert any other CDF to a CUMULATIVE_NUMBER_DISTRIBUTION. More...
 
void cutoffCumulativeNumber (Mdouble quantileMin, Mdouble quantileMax, Mdouble minPolydispersity=0.1)
 cutoff the PSD at given quantiles. More...
 
void cutoffAndSqueezeCumulative (Mdouble quantileMin, Mdouble quantileMax, Mdouble squeeze, Mdouble minPolydispersity=0.1)
 cutoff the PSD at given quantiles and make it less polydisperse by squeezing it. More...
 
Mdouble getMinRadius () const
 Get smallest radius of the PSD. More...
 
Mdouble getMaxRadius () const
 Get largest radius of the PSD. More...
 
std::vector< DistributionElementsgetParticleSizeDistribution () const
 Get the PSD vector. More...
 
void setParticleSizeDistribution (std::vector< DistributionElements >)
 set the PSD by a suitable vector. More...
 
int getInsertedParticleNumber () const
 Get the number of particles already inserted into the simulation. More...
 
void decrementNParticlesPerClass ()
 Decrement nParticlesPerClass_ counter. More...
 
void decrementVolumePerClass (Mdouble volume)
 Decrement volumePerClass_ counter. More...
 
Mdouble getRadius (int index) const
 get a radius at a certain index of the particleSizeDistribution_ More...
 
Mdouble getNumberDx (Mdouble x) const
 Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile x of the number based PSD. More...
 
Mdouble getVolumeDx (Mdouble x) const
 Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile x of the volume based PSD. More...
 
Mdouble getRadiusByQuantile (Mdouble quantile) const
 Calculate the quantile of the PSD. More...
 
Mdouble getQuantileByRadius (Mdouble radius) const
 Calculates the quantile corresponding to a certain radius. More...
 
Mdouble getVolumetricMeanRadius () const
 get a volumetric mean radius of the PSD. More...
 
Mdouble getSizeRatio () const
 get the size ratio (width) of the PSD. More...
 
void cutHighSizeRatio ()
 Check if the size ratio is too high and cut it. More...
 
void setFixedSeed (int seed)
 set a fixed seed for the random number generator; this is used for the PSDSelfTest to reproduce results More...
 

Static Public Member Functions

static PSD getDistributionNormal (Mdouble mean, Mdouble standardDeviation, int numberOfBins)
 
static PSD getDistributionLogNormal (Mdouble mean, Mdouble standardDeviation, int numberOfBins)
 
static std::vector< Mdoublelinspace (Mdouble Min, Mdouble Max, int numberOfBins)
 compute central momenta of the user defined PSD. ‍/ void computeCentralMomenta(); More...
 

Private Attributes

std::vector< DistributionElementsparticleSizeDistribution_
 
std::vector< int > nParticlesPerClass_
 
std::vector< MdoublevolumePerClass_
 
int index_
 
RNG random_
 

Friends

bool operator< (const DistributionElements &l, const DistributionElements &r)
 determines if a certain value of the PSD vector is lower than another one. Used for std::lower_bound() More...
 
bool operator< (const DistributionElements &l, Mdouble r)
 determines if a certain value of the PSD vector is lower than a double. More...
 
std::ostream & operator<< (std::ostream &os, DistributionElements &p)
 Writes to output stream. More...
 
std::istream & operator>> (std::istream &is, DistributionElements &p)
 Reads from input stream. More...
 
Mdouble operator== (DistributionElements l, Mdouble r)
 Determines if a certain value of the PSD vector is equal to a double. More...
 

Detailed Description

Contains a vector with radii and probabilities of a user defined particle size distribution (PSD)

Stores radii and probabilities of a particle size distribution (PSD) in a vector of type DistributionElements and converts them to a PSD which can be used by insertionBoundaries which insert particles into a simulation:

Cumulative distribution function (CDF): gives percentage of particles p_i whose radius r is less than a certain radius r_i. It requires p_0 = 0 and p_end = 1. The CDF's probabilities can be number, length, area or volume based. The cumulative number distribution function (CUMULATIVE_NUMBER_DISTRIBUTION) is used as PSD in MercuryDPM, as it can be interpreted as the probability that a particle's radius is less than r_i: CDF(r<r_i) = p_i.

Probability density function (PDF): p_i is the percentage of particles whose radius is between r_i-1 and r_i. It requires p_0=0 and sum(p_i)=1. The PDF's probabilities can also be number, length, area or volume based. PDF's are utilized to convert any type of PDF to a probability number density function (PROBABILITYDENSITY_NUMBER_DISTRIBUTION) which in a next step are converted to the default CUMULATIVE_NUMBER_DISTRIBUTION.

Sieve data: p_i is the percentage of particles whose radius is between r_i and r_i+1. It requires sum(p_i)=1. relation to PDF: p_i = p(PDF)_i-1. Sieve data is not yet used in this class.

Default distribution is the CUMULATIVE_NUMBER_DISTRIBUTION.

Member Enumeration Documentation

◆ TYPE

enum PSD::TYPE
strong

Enum class which stores the possible types of CDFs and PDFs. Particle size distributions can be represented by different probabilities based on number of particles, length of particles, surface area of particles or volume of particles.

Enumerator
CUMULATIVE_NUMBER_DISTRIBUTION 
CUMULATIVE_LENGTH_DISTRIBUTION 
CUMULATIVE_VOLUME_DISTRIBUTION 
CUMULATIVE_AREA_DISTRIBUTION 
PROBABILITYDENSITY_NUMBER_DISTRIBUTION 
PROBABILITYDENSITY_LENGTH_DISTRIBUTION 
PROBABILITYDENSITY_AREA_DISTRIBUTION 
PROBABILITYDENSITY_VOLUME_DISTRIBUTION 
74  {
75  CUMULATIVE_NUMBER_DISTRIBUTION,
76  CUMULATIVE_LENGTH_DISTRIBUTION,
77  CUMULATIVE_VOLUME_DISTRIBUTION,
78  CUMULATIVE_AREA_DISTRIBUTION,
79  PROBABILITYDENSITY_NUMBER_DISTRIBUTION,
80  PROBABILITYDENSITY_LENGTH_DISTRIBUTION,
81  PROBABILITYDENSITY_AREA_DISTRIBUTION,
82  PROBABILITYDENSITY_VOLUME_DISTRIBUTION
83  };

Constructor & Destructor Documentation

◆ PSD() [1/2]

PSD::PSD ( )

Constructor; sets everything to 0 or default.

Default constructor; sets every data member to 0 or default.

33 {
34 // for (auto& momenta: momenta_)
35 // momenta = 0;
36  index_ = 0;
37  // default seed is zero for reproducibility
39 }
RNG random_
Definition: PSD.h:370
int index_
Definition: PSD.h:365
void setRandomSeed(unsigned long int new_seed)
This is the seed for the random number generator (note the call to seed_LFG is only required really i...
Definition: RNG.cc:53

References index_, random_, and RNG::setRandomSeed().

Referenced by copy().

◆ PSD() [2/2]

PSD::PSD ( const PSD other)

Copy constructor with deep copy.

Copy constructor

45 {
47 // momenta_ = other.momenta_;
48  index_ = other.index_;
49  random_ = other.random_;
50 }
std::vector< DistributionElements > particleSizeDistribution_
Definition: PSD.h:344

References index_, particleSizeDistribution_, and random_.

◆ ~PSD()

PSD::~PSD ( )
default

Destructor; default destructor.

Destructor. Since there are no pointers in this class, there is no need for any actions here.

Member Function Documentation

◆ convertCumulativeToCumulativeNumberDistribution()

void PSD::convertCumulativeToCumulativeNumberDistribution ( TYPE  CDFType)

convert any other CDF to a CUMULATIVE_NUMBER_DISTRIBUTION.

converts any of the CDFTypes to a the default CUMULATIVE_NUMBER_DISTRIBUTION based on their TYPE.

Parameters
[in]PDFTypeType of the PDF: PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_AREA_DISTRIBUTION or PROBABILITYDENSITY_VOLUME_DISTRIBUTION, Where L = Length, A = Area and V = Volume.
Todo:
TP: NOT WORKING! If anyone knows how to do it feel free to add
657 {
658  Mdouble sum = 0;
659  switch (CDFType)
660  {
661  default:
662  logger(ERROR, "Wrong CDFType");
663  break;
665  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
666  {
667  // add conversion here
668 
669  // sum up probabilities
670  sum += it->probability;
671  }
672  // normalize
673  for (auto& p : particleSizeDistribution_)
674  {
675  p.probability /= sum;
676  }
677  break;
679  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
680  {
681  // add conversion here
682 
683  // sum up probabilities
684  sum += it->probability;
685  }
686  // normalize
687  for (auto& p : particleSizeDistribution_)
688  {
689  p.probability /= sum;
690  }
691  break;
693  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
694  {
695  // add conversion here
696 
697  // sum up probabilities
698  sum += it->probability;
699  }
700  // normalize
701  for (auto& p : particleSizeDistribution_)
702  {
703  p.probability /= sum;
704  }
705  break;
706  }
707 }
double Mdouble
Definition: GeneralDefine.h:34
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ ERROR
@ CUMULATIVE_AREA_DISTRIBUTION
@ CUMULATIVE_VOLUME_DISTRIBUTION
@ CUMULATIVE_LENGTH_DISTRIBUTION

References CUMULATIVE_AREA_DISTRIBUTION, CUMULATIVE_LENGTH_DISTRIBUTION, CUMULATIVE_VOLUME_DISTRIBUTION, ERROR, logger, and particleSizeDistribution_.

Referenced by PSDSelfTest::setupInitialConditions().

◆ convertCumulativeToProbabilityDensity()

void PSD::convertCumulativeToProbabilityDensity ( )

Converts a CDF to a PDF by derivation.

Convert any type of CDF to a PDF. Probabilities are derivated for each radius by substracting the CDF probabilities (i.e. pPDF_i = pCDF_i - pCDF_i-1).

547 {
548  // subtract cumulative probabilities
549  Mdouble probabilityOld = 0, probabilityCDF;
550  for (auto& it : particleSizeDistribution_)
551  {
552  probabilityCDF = it.probability;
553  it.probability -= probabilityOld;
554  probabilityOld = probabilityCDF;
555  }
556  // check whether probability density distribution is valid
558 }
void validateProbabilityDensityDistribution()
Validates if the integral of the PDF equals to unity.
Definition: PSD.cc:260

References particleSizeDistribution_, and validateProbabilityDensityDistribution().

Referenced by getVolumeDx(), getVolumetricMeanRadius(), insertManuallyByVolume(), setPSDFromCSV(), and setPSDFromVector().

◆ convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution()

void PSD::convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution ( )

convert a PROBABILITYDENSITY_NUMBER_DISTRIBUTION to a PROBABILITYDENSITY_VOLUME_DISTRIBUTION.

converts a PROBABILITYDENSITY_NUMBER_DISTRIBUTION to a PROBABILITYDENSITY_VOLUME_DISTRIBUTION. Used for getVolumetricMeanRadius() and insertManuallyByVolume().

631 {
632  Mdouble sum = 0;
633  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
634  {
635  it->probability *=
636  0.25 * (square(it->internalVariable) + square((it - 1)->internalVariable)) *
637  (it->internalVariable + (it - 1)->internalVariable);
638  // old conversion
639  //p.probability /= cubic(p.internalVariable);
640  // sum up probabilities
641  sum += it->probability;
642  }
643  // normalize
644  for (auto& p : particleSizeDistribution_)
645  {
646  p.probability /= sum;
647  }
648 }
T square(const T val)
squares a number
Definition: ExtendedMath.h:106

References particleSizeDistribution_, and mathsFunc::square().

Referenced by getVolumeDx(), getVolumetricMeanRadius(), and insertManuallyByVolume().

◆ convertProbabilityDensityToCumulative()

void PSD::convertProbabilityDensityToCumulative ( )

Converts a PDF to a CDF by integration.

Convert any type of PDF to a CDF. Probabilities are integrated for each radius by cumulatively summing them up (i.e. p_i = p_i + p_i-1).

532 {
533  // add up probabilities
534  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
535  {
536  it->probability = std::min(1.0, it->probability + (it - 1)->probability);
537  }
538  // check whether cumulative distribution is valid
540 }
void validateCumulativeDistribution()
Validates if a CDF starts with zero and adds up to unity.
Definition: PSD.cc:213

References particleSizeDistribution_, and validateCumulativeDistribution().

Referenced by getVolumeDx(), insertManuallyByVolume(), setPSDFromCSV(), and setPSDFromVector().

◆ convertProbabilityDensityToProbabilityDensityNumberDistribution()

void PSD::convertProbabilityDensityToProbabilityDensityNumberDistribution ( TYPE  PDFType)

convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION.

converts any of the PDFTypes to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION based on their TYPE. This is a helper function which enables the convertProbabilityDensityToCumulative function to convert the psd into the default TYPE (CUMULATIVE_NUMBER_DISTRIBUTION).

Parameters
[in]PDFTypeType of the PDF: PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_AREA_DISTRIBUTION or PROBABILITYDENSITY_VOLUME_DISTRIBUTION, Where L = Length, A = Area and V = Volume.
567 {
568  Mdouble sum = 0;
569  switch (PDFType)
570  {
571  default:
572  logger(ERROR, "Wrong PDFType");
573  break;
575  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
576  {
577  it->probability /= 0.5 * (it->internalVariable + (it - 1)->internalVariable);
578  // old conversion
579  //p.probability /= p.internalVariable;
580  // sum up probabilities
581  sum += it->probability;
582  }
583  // normalize
584  for (auto& p : particleSizeDistribution_)
585  {
586  p.probability /= sum;
587  }
588  break;
590  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
591  {
592  it->probability /=
593  1.0 / 3.0 * (square(it->internalVariable) + it->internalVariable * (it - 1)->internalVariable +
594  square((it - 1)->internalVariable));
595  // old conversion
596  //p.probability /= square(p.internalVariable);
597  // sum up probabilities
598  sum += it->probability;
599  }
600  // normalize
601  for (auto& p : particleSizeDistribution_)
602  {
603  p.probability /= sum;
604  }
605  break;
607  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
608  {
609  it->probability /=
610  0.25 * (square(it->internalVariable) + square((it - 1)->internalVariable)) *
611  (it->internalVariable + (it - 1)->internalVariable);
612  // old conversion
613  //p.probability /= cubic(p.internalVariable);
614  // sum up probabilities
615  sum += it->probability;
616  }
617  // normalize
618  for (auto& p : particleSizeDistribution_)
619  {
620  p.probability /= sum;
621  }
622  break;
623  }
624 }
@ PROBABILITYDENSITY_VOLUME_DISTRIBUTION
@ PROBABILITYDENSITY_LENGTH_DISTRIBUTION
@ PROBABILITYDENSITY_AREA_DISTRIBUTION

References ERROR, logger, particleSizeDistribution_, PROBABILITYDENSITY_AREA_DISTRIBUTION, PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_VOLUME_DISTRIBUTION, and mathsFunc::square().

Referenced by insertManuallyByVolume(), setPSDFromCSV(), and setPSDFromVector().

◆ copy()

PSD * PSD::copy ( ) const

Creates a copy on the heap and returns a pointer.

Copy method; creates a copy on the heap and returns its pointer.

Returns
pointer to the copy on the heap
65 {
66 #ifdef DEBUG_CONSTRUCTOR
67  std::cout << "PSD::copy() const finished" << std::endl;
68 #endif
69  return new PSD(*this);
70 }
PSD()
Constructor; sets everything to 0 or default.
Definition: PSD.cc:32

References PSD().

◆ cutHighSizeRatio()

void PSD::cutHighSizeRatio ( )

Check if the size ratio is too high and cut it.

Checks if the Size ratio of the PSD is too high and cuts the PSD at head and tail by 10 percent to avoid inaccurate results.

873 {
874  Mdouble SR = getSizeRatio();
875  if (SR > 100)
876  {
877  logger(WARN, "Size ratio > 100; Cutting the PSD to avoid inaccurate results");
878  cutoffCumulativeNumber(0.1, 0.9, 0.5);
879  }
880 }
@ WARN
Mdouble getSizeRatio() const
get the size ratio (width) of the PSD.
Definition: PSD.cc:861
void cutoffCumulativeNumber(Mdouble quantileMin, Mdouble quantileMax, Mdouble minPolydispersity=0.1)
cutoff the PSD at given quantiles.
Definition: PSD.cc:715

References cutoffCumulativeNumber(), getSizeRatio(), logger, and WARN.

◆ cutoffAndSqueezeCumulative()

void PSD::cutoffAndSqueezeCumulative ( Mdouble  quantileMin,
Mdouble  quantileMax,
Mdouble  squeeze,
Mdouble  minPolydispersity = 0.1 
)

cutoff the PSD at given quantiles and make it less polydisperse by squeezing it.

Cuts off the CDF at given minimum and maximum quantiles, applies a minimum polydispersity at the base and squeezes the distribution to make it less polydisperse.

Parameters
[in]quantileMinundersize quantile to cut off the lower part of the CDF.
[in]quantileMaxoversize quantile to cut off the upper part of the CDF.
[in]squeezeapplies a squeezing factor ([0,1]) which determines the degree the PDF gets squeezed.
[in]minPolydispersityapplies a minimum of polydispersity ([0,1]) at the base of the CDF.
751 {
752  Mdouble r50 = 0.5 * PSD::getNumberDx(50);
753  // cut off
754  cutoffCumulativeNumber(quantileMin, quantileMax, minPolydispersity);
755  // squeeze psd
756  for (auto& p: particleSizeDistribution_)
757  {
758  p.internalVariable = r50 + (p.internalVariable - r50) * squeeze;
759  }
760 }
Mdouble getNumberDx(Mdouble x) const
Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile x of the number based PSD.
Definition: PSD.cc:767

References cutoffCumulativeNumber(), getNumberDx(), and particleSizeDistribution_.

◆ cutoffCumulativeNumber()

void PSD::cutoffCumulativeNumber ( Mdouble  quantileMin,
Mdouble  quantileMax,
Mdouble  minPolydispersity = 0.1 
)

cutoff the PSD at given quantiles.

Cuts off the CDF at given minimum and maximum quantiles and applies a minimum polydispersity at the base.

Parameters
[in]quantileMinundersize quantile to cut off the lower part of the CDF.
[in]quantileMaxoversize quantile to cut off the upper part of the CDF.
[in]minPolydispersityApplies a minimum of polydispersity ([0,1]) at the base of the CDF.
716 {
717  Mdouble radiusMin = getRadiusByQuantile(quantileMin);
718  Mdouble radiusMax = getRadiusByQuantile(quantileMax);
719  // to get a minimum polydispersity at the base
720  Mdouble radiusMinCut = std::min(radiusMin * (1 + minPolydispersity), radiusMax);
721  // cut off min
722  while (particleSizeDistribution_.front().internalVariable <= radiusMinCut)
723  {
725  }
726  particleSizeDistribution_.insert(particleSizeDistribution_.begin(), {radiusMinCut, quantileMin});
727  particleSizeDistribution_.insert(particleSizeDistribution_.begin(), {radiusMin, 0});
728  // cut off max
729  while (particleSizeDistribution_.back().internalVariable >= radiusMax)
730  {
731  particleSizeDistribution_.pop_back();
732  }
733  Mdouble radiusMaxCut = std::max(radiusMax - (1 - minPolydispersity) * (radiusMax - particleSizeDistribution_.back()
734  .internalVariable), radiusMin);
735  particleSizeDistribution_.push_back({radiusMaxCut, quantileMax});
736  particleSizeDistribution_.push_back({radiusMax, 1});
737  logger(INFO, "PSD was cut successfully and now has a size ratio of %", getSizeRatio());
738 }
@ INFO
Mdouble getRadiusByQuantile(Mdouble quantile) const
Calculate the quantile of the PSD.
Definition: PSD.cc:791

References getRadiusByQuantile(), getSizeRatio(), INFO, logger, and particleSizeDistribution_.

Referenced by cutHighSizeRatio(), and cutoffAndSqueezeCumulative().

◆ decrementNParticlesPerClass()

void PSD::decrementNParticlesPerClass ( )

Decrement nParticlesPerClass_ counter.

Decrement the nParticlesPerClass_ counter of the last inserted class by 1. This is utilized when a particle is generated but failed to be placed into an insertionBoundary.

843 {
845 }
std::vector< int > nParticlesPerClass_
Definition: PSD.h:351

References index_, and nParticlesPerClass_.

◆ decrementVolumePerClass()

void PSD::decrementVolumePerClass ( Mdouble  volume)

Decrement volumePerClass_ counter.

Decrement the volumePerClass_ counter of the last inserted class by the volume of the particle. This is utilized when a particle is generated but failed to be placed into an insertionBoundary.

Parameters
[in]volumeVolume of the particle which failed to be inserted.
853 {
854  volumePerClass_[index_]-= volume;
855 }
std::vector< Mdouble > volumePerClass_
Definition: PSD.h:360

References index_, and volumePerClass_.

◆ drawSample()

Mdouble PSD::drawSample ( )

Draw a sample radius from a CUMULATIVE_NUMBER_DISTRIBUTION.

Draws a sample probability of a real uniform distribution. A random number is generated in range [0,1] and by linear interpolation a suitable radius is returned. This function is only valid for CumulativeNumberDistributions as particles are drawn and not volumes, areas or lengths.

Returns
A Radius for a randomly assigned probability.
115 {
116  // draw a number between 0 and 1, uniformly distributed
117  Mdouble prob = random_.getRandomNumber(0, 1);
118  // find the interval [low,high] of the psd in which the number sits
119  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(), prob);
120  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
121  Mdouble rMin = low->internalVariable;
122  Mdouble rMax = high->internalVariable;
123  Mdouble pMin = low->probability;
124  Mdouble pMax = high->probability;
125  // interpolate linearly between [low.radius,high.radius] (assumption: CDF is piecewise linear)
126  Mdouble a = (prob - pMin) / (pMax - pMin);
127  return a * rMin + (1 - a) * rMax;
128 }
Mdouble getRandomNumber()
This is a random generating routine can be used for initial positions.
Definition: RNG.cc:143

References RNG::getRandomNumber(), particleSizeDistribution_, and random_.

◆ getDistributionLogNormal()

static PSD PSD::getDistributionLogNormal ( Mdouble  mean,
Mdouble  standardDeviation,
int  numberOfBins 
)
inlinestatic
164  {
165  PSD psd;
166  psd.setDistributionLogNormal(mean, standardDeviation, numberOfBins);
167  return psd;
168  }
Contains a vector with radii and probabilities of a user defined particle size distribution (PSD)
Definition: PSD.h:65
void setDistributionLogNormal(Mdouble mean, Mdouble standardDeviation, int numberOfBins)
create a PSD vector for a normal distribution.
Definition: PSD.cc:357

References setDistributionLogNormal().

Referenced by DistributionSelfTest::setupInitialConditions().

◆ getDistributionNormal()

static PSD PSD::getDistributionNormal ( Mdouble  mean,
Mdouble  standardDeviation,
int  numberOfBins 
)
inlinestatic
153  {
154  PSD psd;
155  psd.setDistributionNormal(mean, standardDeviation, numberOfBins);
156  return psd;
157  }
void setDistributionNormal(Mdouble mean, Mdouble standardDeviation, int numberOfBins)
create a PSD vector for a normal distribution.
Definition: PSD.cc:323

References setDistributionNormal().

Referenced by Material::setPSD(), Drum::setupInitialConditions(), and RotatingDrumWet::setupInitialConditions().

◆ getInsertedParticleNumber()

int PSD::getInsertedParticleNumber ( ) const

Get the number of particles already inserted into the simulation.

Gets the number of particles already inserted into the simulation by summing up the particles inserted in each class.

Returns
An integer containing the number of particles already inserted into the simulation.
924 {
925  int sum = 0;
926  for (auto& it: nParticlesPerClass_)
927  sum += it;
928  return sum;
929 }

References nParticlesPerClass_.

◆ getMaxRadius()

Mdouble PSD::getMaxRadius ( ) const

Get largest radius of the PSD.

Gets the maximum radius of the PSD.

Returns
A double which corresponds to the maximum radius of the PSD.
896 {
897  return particleSizeDistribution_.back().internalVariable;
898 }

References particleSizeDistribution_.

Referenced by getSizeRatio(), GranuDrum::GranuDrum(), and GranuHeap::GranuHeap().

◆ getMinRadius()

Mdouble PSD::getMinRadius ( ) const

Get smallest radius of the PSD.

Gets the minimal radius of the PSD.

Returns
A double which corresponds to the minimal radius of the PSD.
887 {
888  return particleSizeDistribution_[0].internalVariable;
889 }

References particleSizeDistribution_.

Referenced by getSizeRatio(), GranuHeap::GranuHeap(), Calibration::setSpecies(), and Material::setSpecies().

◆ getNumberDx()

Mdouble PSD::getNumberDx ( Mdouble  x) const

Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile x of the number based PSD.

Gets the diameter from a certain percentile of the number based PSD.

Returns
A double which is the diameter corresponding to a certain percentile.
Parameters
[in]xdouble which determines the obtained diameter as a percentile of the PSD.
768 {
769  return 2.0 * getRadiusByQuantile(x / 100);
770 }

References getRadiusByQuantile().

Referenced by cutoffAndSqueezeCumulative(), and GranuHeap::GranuHeap().

◆ getParticleSizeDistribution()

std::vector< DistributionElements > PSD::getParticleSizeDistribution ( ) const

Get the PSD vector.

Gets the vector containing radii and probabilities of the PSD.

Returns
A vector containing radii and probabilities of the PSD.
905 {
907 }

References particleSizeDistribution_.

◆ getQuantileByRadius()

Mdouble PSD::getQuantileByRadius ( Mdouble  radius) const

Calculates the quantile corresponding to a certain radius.

Calculates the quantile corresponding to a certain radius.

Parameters
radiusThe radius to find the quantile for.
Returns
The quantile found.
811 {
812  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(),
813  radius, [](const DistributionElements& rp, Mdouble value){ return rp.internalVariable < value; });
814  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
815  if (high->internalVariable == low->internalVariable)
816  return high->probability;
817  else
818  return low->probability + (high->probability - low->probability) * (radius - low->internalVariable) / (high->internalVariable - low->internalVariable);
819 }
class of DistributionElements which stores internalVariables and probabilities of a distribution....
Definition: DistributionElements.h:34

References particleSizeDistribution_.

◆ getRadius()

Mdouble PSD::getRadius ( int  index) const

get a radius at a certain index of the particleSizeDistribution_

 \details Compute the raw momenta of the inserted PSD by converting it to a PDF, calculating the moments m_i according
 to \f$ m_i = \sum_{j=0}^n \f$ scaling it by the number
 of particles inserted into the simulation (moments are computed from a PROBABILITYDENSITY_NUMBER_DISTRIBUTION) and
 converting it back to a CDF.
 See <a href="https://en.wikipedia.org/wiki/Moment_(mathematics)#Significance_of_the_moments">Wikipedia</a> for
 details.
&zwj;/

void PSD::computeRawMomenta() { convertCumulativeToProbabilityDensity(); for (size_t im = 0; im < momenta_.size(); ++im) { // prevent summing up of moments for each time step of the simulation momenta_[im] = 0; for (auto& it : particleSizeDistribution_) { momenta_[im] += std::pow(it.internalVariable, im) * it.probability; } } // zeroth-moment equals particle number for a PROBABILITYDENSITY_NUMBER_DISTRIBUTION momenta_[0] *= getInsertedParticleNumber(); convertProbabilityDensityToCumulative(); }

/*!

Compute the central momenta of the PSD from their respective raw momenta. ‍/ void PSD::computeCentralMomenta() { computeRawMomenta(); Mdouble mean = momenta_[1]; momenta_[5] += -5 * mean * momenta_[4] + 10 * mean * mean * momenta_[3]

  • 10 * mean * mean * mean * momenta_[2] + 4 * mean * mean * mean * mean * mean; momenta_[4] += -4 * mean * momenta_[3] + 6 * mean * mean * momenta_[2] - 3 * mean * mean * mean * mean; momenta_[3] += -3 * mean * momenta_[2] + 2 * mean * mean * mean; momenta_[2] += -mean * mean; }

/*!

Compute the standardised momenta of the PSD from their respective central momenta. ‍/ void PSD::computeStandardisedMomenta() { computeCentralMomenta(); Mdouble std = std::sqrt(momenta_[2]); momenta_[3] /= std * std * std; momenta_[4] /= std * std * std * std; momenta_[5] /= std * std * std * std * std; }

/*!

Gets the radius of a particle from the PSD.

Parameters
[in]iAn integer which is the index of the vector containing the radius.
Returns
A double which corresponds to the radius of the particle.
988 {
989  return particleSizeDistribution_[index].internalVariable;
990 }

References particleSizeDistribution_.

◆ getRadiusByQuantile()

Mdouble PSD::getRadiusByQuantile ( Mdouble  quantile) const

Calculate the quantile of the PSD.

gets the radius from a certain quantile of the PSD

Returns
A double which is the radius corresponding to a certain quantile of the PSD.
Parameters
[in]quantiledouble which determines the returned radius as a quantile of the PSD.
792 {
793  logger.assert_always(quantile <= 1 && quantile >= 0, "quantile is not between 0 and 1");
794  // find the quantile corresponding to the PSD
795  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(), quantile);
796  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
797  if (high->probability == low->probability)
798  return high->internalVariable;
799  else
800  return low->internalVariable +
801  (high->internalVariable - low->internalVariable) * (quantile - low->probability) /
802  (high->probability - low->probability);
803 }

References logger, and particleSizeDistribution_.

Referenced by cutoffCumulativeNumber(), getNumberDx(), and getVolumeDx().

◆ getSizeRatio()

Mdouble PSD::getSizeRatio ( ) const

get the size ratio (width) of the PSD.

Gets the size ratio (width) of the PSD defined by the ratio of minimum to maximum particle radius.

Returns
A double which corresponds to the size ratio of the PSD.
862 {
863  Mdouble rMin = getMaxRadius();
864  Mdouble rMax = getMinRadius();
865  return rMin / rMax;
866 }
Mdouble getMinRadius() const
Get smallest radius of the PSD.
Definition: PSD.cc:886
Mdouble getMaxRadius() const
Get largest radius of the PSD.
Definition: PSD.cc:895

References getMaxRadius(), and getMinRadius().

Referenced by cutHighSizeRatio(), cutoffCumulativeNumber(), and setPSDFromCSV().

◆ getVolumeDx()

Mdouble PSD::getVolumeDx ( Mdouble  x) const

Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile x of the volume based PSD.

Gets the diameter from a certain percentile of the volume based PSD.

Returns
A double which is the diameter corresponding to a certain percentile.
Parameters
[in]xdouble which determines the obtained diameter as a percentile of the PSD.
778 {
779  PSD psd = *this;
783  return 2.0 * psd.getRadiusByQuantile(x / 100);
784 }
void convertCumulativeToProbabilityDensity()
Converts a CDF to a PDF by derivation.
Definition: PSD.cc:546
void convertProbabilityDensityToCumulative()
Converts a PDF to a CDF by integration.
Definition: PSD.cc:531
void convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution()
convert a PROBABILITYDENSITY_NUMBER_DISTRIBUTION to a PROBABILITYDENSITY_VOLUME_DISTRIBUTION.
Definition: PSD.cc:630

References convertCumulativeToProbabilityDensity(), convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution(), convertProbabilityDensityToCumulative(), and getRadiusByQuantile().

Referenced by GranuDrum::GranuDrum(), GranuHeap::GranuHeap(), Calibration::setSpecies(), and Material::setSpecies().

◆ getVolumetricMeanRadius()

Mdouble PSD::getVolumetricMeanRadius ( ) const

get a volumetric mean radius of the PSD.

Gets a radius such that a monodisperse system has the same number of particles as a polydisperse system. (i.e. mean += p_i * 0.5*(r_i^3 + r_i-1^3)

Returns
A double which corresponds to the volumetric mean radius.
827 {
828  PSD psd = *this;
831  Mdouble mean = 0;
832  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
833  mean += it->probability * 0.5 * (cubic(it->internalVariable) + cubic((it - 1)->internalVariable));
834  mean = pow(mean, 1. / 3.);
835  return mean;
836 }
T cubic(const T val)
calculates the cube of a number
Definition: ExtendedMath.h:115

References convertCumulativeToProbabilityDensity(), convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution(), mathsFunc::cubic(), and particleSizeDistribution_.

◆ insertManuallyByVolume()

Mdouble PSD::insertManuallyByVolume ( Mdouble  volume)

Draw sample radius manually per size class and check the volumeAllowed of each size class to insert the PSD as accurate as possible.

Draws a sample probability of a real uniform distribution within a given size class. A random number is generated in the size class range [r_i,r_i+1] and by linear interpolation a suitable radius is returned. from a CUMULATIVE_VOLUME_DISTRIBUTION the volumeAllowed of each class is checked to insert the PSD as accurate as possible. This function is only valid for cumulativeNumberDistributions as particles are drawn and not volumes, areas or lengths. Furthermore this insertion routine is most accurate for non-continuous particle insertion.

Parameters
[in]volumevolume of the geometry to be filled.
Returns
A Radius for a randomly assigned probability of a specific size class.
140 {
141  // initialize the particleNumberPerClass vector if empty.
142  if (nParticlesPerClass_.empty())
144  // initialize the particleNumberPerClass vector if empty.
145  if (volumePerClass_.empty())
147 
148  for (auto it = particleSizeDistribution_.end() - 1; it != particleSizeDistribution_.begin(); --it)
149  {
150  static std::mt19937 gen(0);
151  static std::uniform_real_distribution<Mdouble> dist(0, 1);
152  Mdouble prob = dist(gen);
153  // map the probability to the current class interval
154  prob = (it - 1)->probability + (it->probability - (it - 1)->probability) * prob;
155  // find the interval [low,high] of the psd in which the number sits
156  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(), prob);
157  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
158  Mdouble rMin = low->internalVariable;
159  Mdouble rMax = high->internalVariable;
160  Mdouble pMin = low->probability;
161  Mdouble pMax = high->probability;
162  // interpolate linearly between [low.internalVariable,high.internalVariable] (assumption: CDF is piecewise linear)
163  index_ = std::distance(particleSizeDistribution_.begin(), high);
164  Mdouble a = (prob - pMin) / (pMax - pMin);
165  Mdouble rad = a * rMin + (1 - a) * rMax;
166  //\todo generalize this to work for non-spherical particles
167  // Compare inserted volume against volumeAllowed (only works for spherical at the moment)
168  Mdouble radVolume = 4.0 / 3.0 * constants::pi * rad * rad * rad;
171  Mdouble volumeAllowed = particleSizeDistribution_[index_].probability * volume;
174  if (volumePerClass_[index_] > volumeAllowed)
175  {
176  continue;
177  }
178  else if (radVolume + volumePerClass_[index_] > volumeAllowed)
179  {
180  Mdouble differenceVolumeLow = -(volumePerClass_[index_] - volumeAllowed);
181  Mdouble differenceVolumeHigh = radVolume + volumePerClass_[index_] - volumeAllowed;
182  Mdouble volumeRatio = differenceVolumeLow / differenceVolumeHigh;
183  // If volumeRatio > 1 it will insert anyways, because it should be no problem for the distribution
184  prob = dist(gen);
185  if (prob <= volumeRatio)
186  {
188  volumePerClass_[index_] += radVolume;
189  return rad;
190  }
191  else
192  {
193  continue;
194  }
195  }
196  else
197  {
199  volumePerClass_[index_] += radVolume;
200  return rad;
201  }
202 
203  }
204  return 0;
205 }
void convertProbabilityDensityToProbabilityDensityNumberDistribution(TYPE PDFType)
convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION.
Definition: PSD.cc:566
const Mdouble pi
Definition: ExtendedMath.h:45

References convertCumulativeToProbabilityDensity(), convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution(), convertProbabilityDensityToCumulative(), convertProbabilityDensityToProbabilityDensityNumberDistribution(), index_, nParticlesPerClass_, particleSizeDistribution_, constants::pi, PROBABILITYDENSITY_VOLUME_DISTRIBUTION, and volumePerClass_.

◆ linspace()

std::vector< Mdouble > PSD::linspace ( Mdouble  Min,
Mdouble  Max,
int  numberOfBins 
)
static

compute central momenta of the user defined PSD. ‍/ void computeCentralMomenta();

     \brief compute raw momenta of the user defined PSD.
    &zwj;/

void computeRawMomenta();

/*!

/*!

compute standardised momenta of the user defined PSD. ‍/ void computeStandardisedMomenta();

/*!

get momenta of the user defined PSD. ‍/ std::array<Mdouble, 6> getMomenta() const;

/*!
   \brief create a vector of linearly spaced values.

creates a vector of doubles containing linearly spaced values between Min and Max.

Parameters
[in]MinA double which is the minimum value of the vector.
[in]MaxA double which is the maximum value of the vector.
[in]numberOfBinsAn integer which is the number of bins of the vector.
Returns
A vector of doubles containing linearly spaced values between Min and Max.
1000 {
1001  Mdouble dx = (Max - Min) / static_cast<Mdouble>(numberOfBins - 1);
1002  Mdouble val;
1003  std::vector<Mdouble> linearVector(numberOfBins);
1004  typename std::vector<Mdouble>::iterator x;
1005  for (x = linearVector.begin(), val = Min; x != linearVector.end(); ++x, val += dx)
1006  {
1007  *x = val;
1008  }
1009  // ensure that last value is equal to Max.
1010  linearVector.pop_back();
1011  linearVector.push_back(Max);
1012  return linearVector;
1013 }

Referenced by setDistributionLogNormal(), setDistributionNormal(), and setDistributionUniform().

◆ printPSD()

void PSD::printPSD ( ) const

Prints radii and probabilities of the PSD vector.

Prints the radii [m] and probabilities [%] of the psd vector. It currently supports nanometers, micrometers, milimeters and meters as size units.

77 {
78  if (particleSizeDistribution_.front().internalVariable > 1e-1)
79  {
80  for (const auto p: particleSizeDistribution_)
81  {
82  logger(INFO, "%m\t %\%", p.internalVariable, p.probability * 100);
83  }
84  }
85  else if (particleSizeDistribution_.front().internalVariable > 1e-4)
86  {
87  for (const auto p: particleSizeDistribution_)
88  {
89  logger(INFO, "%mm\t %\%", p.internalVariable * 1000, p.probability * 100);
90  }
91  }
92  else if (particleSizeDistribution_.front().internalVariable > 1e-7)
93  {
94  for (const auto p: particleSizeDistribution_)
95  {
96  logger(INFO, "%um\t %\%", p.internalVariable * 1e6, p.probability * 100);
97  }
98  }
99  else
100  {
101  for (const auto p: particleSizeDistribution_)
102  {
103  logger(INFO, "%nm\t %\%", p.internalVariable * 1e9, p.probability * 100);
104  }
105  }
106 }

References INFO, logger, and particleSizeDistribution_.

◆ setDistributionLogNormal()

void PSD::setDistributionLogNormal ( Mdouble  mean,
Mdouble  standardDeviation,
int  numberOfBins 
)

create a PSD vector for a normal distribution.

sets the particle size distribution to a discretised normal (gaussian) cumulative number distribution, which covers the range of 3 * standardDeviation (99,73% of all values covered).

Parameters
[in]meanDouble representing the mean of the particle size distribution
[in]standardDeviationDouble representing the standard deviation of the particle size distribution
[in]numberOfBinsInteger determining the number of bins (aka. particle size classes or resolution) of the particle size distribution See https://en.cppreference.com/w/cpp/numeric/random/lognormal_distribution
358 {
359  //setDistributionNormal(mean, standardDeviation, numberOfBins);
360  if (!particleSizeDistribution_.empty())
361  {
363  }
364  Mdouble radMin = mean - 3 * standardDeviation;
365  Mdouble radMax = mean + 3 * standardDeviation;
366  std::vector<Mdouble> radii = linspace(radMin, radMax, numberOfBins);
367  std::vector<Mdouble> probabilities;
368  for (int i = 0; i < radii.size(); i++)
369  {
370  Mdouble probability = 0.5 * (1 + erf((radii[i] - mean) / (sqrt(2) * standardDeviation)));
371  probabilities.push_back(probability);
372  }
373  for (int j = 0; j < radii.size(); j++)
374  {
375  particleSizeDistribution_.push_back({radii[j], probabilities[j]});
376  }
378  for (auto& p: particleSizeDistribution_)
379  {
380  p.internalVariable = exp(p.internalVariable);
381  }
382 }
static std::vector< Mdouble > linspace(Mdouble Min, Mdouble Max, int numberOfBins)
compute central momenta of the user defined PSD. ‍/ void computeCentralMomenta();
Definition: PSD.cc:999
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
Mdouble exp(Mdouble Exponent)
Definition: ExtendedMath.cc:84

References mathsFunc::exp(), constants::i, linspace(), particleSizeDistribution_, and validateCumulativeDistribution().

Referenced by getDistributionLogNormal().

◆ setDistributionNormal()

void PSD::setDistributionNormal ( Mdouble  mean,
Mdouble  standardDeviation,
int  numberOfBins 
)

create a PSD vector for a normal distribution.

sets the particle size distribution to a discretised normal (gaussian) cumulative number distribution, which covers the range of 3 * standardDeviation (99,73% of all values covered).

Parameters
[in]meanDouble representing the mean of the particle size distribution
[in]standardDeviationDouble representing the standard deviation of the particle size distribution
[in]numberOfBinsInteger determining the number of bins (aka. particle size classes or resolution) of the particle size distribution
324 {
325  logger.assert_always(mean > 3 * standardDeviation,
326  "Reduce standardDeviation of your normal distribution to avoid negative radii; The mean "
327  "should be greater than 3*standardDeviation");
328  if (!particleSizeDistribution_.empty())
329  {
331  }
332  Mdouble radMin = mean - 3 * standardDeviation;
333  Mdouble radMax = mean + 3 * standardDeviation;
334  std::vector<Mdouble> radii = linspace(radMin, radMax, numberOfBins);
335  std::vector<Mdouble> probabilities;
336  for (int i = 0; i < radii.size(); i++)
337  {
338  Mdouble probability = 0.5 * (1 + erf((radii[i] - mean) / (sqrt(2) * standardDeviation)));
339  probabilities.push_back(probability);
340  }
341  for (int j = 0; j < radii.size(); j++)
342  {
343  particleSizeDistribution_.push_back({radii[j], probabilities[j]});
344  }
346 }

References constants::i, linspace(), logger, particleSizeDistribution_, and validateCumulativeDistribution().

Referenced by getDistributionNormal(), and DistributionToPSDSelfTest::setupInitialConditions().

◆ setDistributionUniform()

void PSD::setDistributionUniform ( Mdouble  radMin,
Mdouble  radMax,
int  numberOfBins 
)

create a PSD vector for a uniform distribution.

sets the particle size distribution to a discretised uniform (linear) cumulative number distribution

Parameters
[in]radMinDouble representing The smallest particle radius of the particle size distribution
[in]radMaxDouble representing the biggest particle radius of the particle size distribution
[in]numberOfBinsInteger determining the number of bins (aka. particle size classes or resolution) of the particle size distribution
300 {
301  if (!particleSizeDistribution_.empty())
302  {
304  }
305  std::vector<Mdouble> probabilities = linspace(0.0, 1.0, numberOfBins);
306  std::vector<Mdouble> radii = linspace(radMin, radMax, numberOfBins);
307  // combine radii and probabilities
308  for (int i = 0; i < radii.size(); ++i)
309  {
310  particleSizeDistribution_.push_back({radii[i], probabilities[i]});
311  }
313 }

References constants::i, linspace(), particleSizeDistribution_, and validateCumulativeDistribution().

Referenced by BoundariesSelfTest::BoundariesSelfTest(), FluxBoundarySelfTest::FluxBoundarySelfTest(), CubeInsertionBoundary::set(), InsertionBoundarySelfTest::setupInitialConditions(), FullRestartTest::setupInitialConditions(), Chute::setupInitialConditions(), ChuteWithHopper::setupInitialConditions(), and T_protectiveWall::T_protectiveWall().

◆ setFixedSeed()

void PSD::setFixedSeed ( int  seed)
inline

set a fixed seed for the random number generator; this is used for the PSDSelfTest to reproduce results

310  {
311 // random_.setLinearCongruentialGeneratorParmeters(0,0,1);
312  random_.setRandomSeed(seed);
313  }

References random_, and RNG::setRandomSeed().

◆ setParticleSizeDistribution()

void PSD::setParticleSizeDistribution ( std::vector< DistributionElements particleSizeDistribution)

set the PSD by a suitable vector.

sets the PSD from a vector of the DistributionElements class; used to read in PSDs from a restart file.

Parameters
[in]particleSizeDistributionvector containing the radii and probabilities specifying the PSD.
914 {
915  particleSizeDistribution_ = particleSizeDistribution;
916 }

References particleSizeDistribution_.

Referenced by convertPSD2ToPSD(), and PSDSelfTest::setupInitialConditions().

◆ setPSDFromCSV()

void PSD::setPSDFromCSV ( const std::string &  fileName,
TYPE  PSDType,
bool  headings = false,
Mdouble  unitScalingFactorRadii = 1.0 
)

read in the PSD vector with probabilities and radii saved in a .csv file.

creates the PSD vector from probabilities and radii saved in a .csv file. Radii should be located at the first column and probabilities at the second column of the file. The Type of PSD will be converted to the default cumulative number distribution function (CUMULATIVE_NUMBER_DISTRIBUTION) for further processing.

Parameters
[in]fileNameName of the .csv file containing the radii and probabilities of the PSD.
[in]PSDTypeType of the PSD: CUMULATIVE_VOLUME_DISTRIBUTION, CUMULATIVE_NUMBER_DISTRIBUTION, CUMULATIVE_LENGTH_DISTRIBUTION, CUMULATIVE_AREA_DISTRIBUTION, PROBABILITYDENSITY_VOLUME_DISTRIBUTION, PROBABILITYDENSITY_NUMBER_DISTRIBUTION, PROBABILITYDENSITY_LENGTH_DISTRIBUTION PROBABILITYDENSITY_AREA_DISTRIBUTION.
[in]headingsIf TRUE the file is assumed to have headings and the first row will be skipped. If FALSE the file has no headings and the file will be read in as is. Default is FALSE.
[in]unitScalingFactorRadiiScaling factor of radii to match SI-units.
463 {
464  // read in csv file using the csvReader class
465  csvReader csv;
466  csv.setHeader(headings);
467  csv.read(fileName);
468  std::vector<Mdouble> radii = csv.getFirstColumn(unitScalingFactorRadii);
469  std::vector<Mdouble> probabilities = csv.getSecondColumn(1.0);
470  logger.assert_always(radii.size() == probabilities.size(), "The radii and probabilities vector have to be the "
471  "same size");
472  // combine radii and probabilities
473  for (int i = 0; i < radii.size(); ++i)
474  {
475  particleSizeDistribution_.push_back({radii[i], probabilities[i]});
476  }
477  logger.assert_always(!particleSizeDistribution_.empty(), "PSD cannot be empty");
478  switch (PSDType)
479  {
480  // default case is a CUMULATIVE_NUMBER_DISTRIBUTION
481  default:
483  break;
490  break;
496  break;
503  break;
507  break;
512  break;
517  break;
522  break;
523  }
524  logger(INFO, "A PSD with size ratio % is now ready to be set", getSizeRatio());
525 }
@ PROBABILITYDENSITY_NUMBER_DISTRIBUTION
Enables reading of .csv files into MercuryDPM.
Definition: csvReader.h:46
std::vector< Mdouble > getSecondColumn(Mdouble scalingFactor)
Get second column of a .csv file and return it as a double.
Definition: csvReader.cc:145
void read(const std::string &filename)
Reads .csv files into Mercury.
Definition: csvReader.cc:40
void setHeader(bool headings)
Set the boolean hasHeader_.
Definition: csvReader.cc:109
std::vector< Mdouble > getFirstColumn(Mdouble scalingFactor)
Get first column of a .csv file and return it as a double.
Definition: csvReader.cc:128

References convertCumulativeToProbabilityDensity(), convertProbabilityDensityToCumulative(), convertProbabilityDensityToProbabilityDensityNumberDistribution(), CUMULATIVE_AREA_DISTRIBUTION, CUMULATIVE_LENGTH_DISTRIBUTION, CUMULATIVE_VOLUME_DISTRIBUTION, csvReader::getFirstColumn(), csvReader::getSecondColumn(), getSizeRatio(), constants::i, INFO, logger, particleSizeDistribution_, PROBABILITYDENSITY_AREA_DISTRIBUTION, PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_NUMBER_DISTRIBUTION, PROBABILITYDENSITY_VOLUME_DISTRIBUTION, csvReader::read(), csvReader::setHeader(), validateCumulativeDistribution(), and validateProbabilityDensityDistribution().

Referenced by MultiplePSDSelfTest::setupInitialConditions(), PSDManualInsertionSelfTest::setupInitialConditions(), and PSDSelfTest::setupInitialConditions().

◆ setPSDFromVector()

MERCURYDPM_DEPRECATED void PSD::setPSDFromVector ( std::vector< DistributionElements psdVector,
TYPE  PSDType 
)

Deprecated version of reading in PSDs from a vector.

creates the psd vector from radii and probabilities filled in by hand. The Type of PSD will be converted to the default cumulative number distribution function (CUMULATIVE_NUMBER_DISTRIBUTION) for further processing.

Parameters
[in]psdVectorVector containing radii and probabilities ([0,1]).
[in]PSDTypeType of the PSD: CUMULATIVE_VOLUME_DISTRIBUTION, CUMULATIVE_NUMBER_DISTRIBUTION, CUMULATIVE_LENGTH_DISTRIBUTION, CUMULATIVE_AREA_DISTRIBUTION, PROBABILITYDENSITY_VOLUME_DISTRIBUTION, PROBABILITYDENSITY_NUMBER_DISTRIBUTION, PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_AREA_DISTRIBUTION.
397 {
398  particleSizeDistribution_ = psdVector;
399  switch (PSDType)
400  {
401  // default case is a cumulative number distribution (CND)
402  default:
404  break;
411  break;
418  break;
424  break;
429  break;
433  break;
438  break;
443  break;
444  }
445 }

References convertCumulativeToProbabilityDensity(), convertProbabilityDensityToCumulative(), convertProbabilityDensityToProbabilityDensityNumberDistribution(), CUMULATIVE_AREA_DISTRIBUTION, CUMULATIVE_LENGTH_DISTRIBUTION, CUMULATIVE_VOLUME_DISTRIBUTION, particleSizeDistribution_, PROBABILITYDENSITY_AREA_DISTRIBUTION, PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_NUMBER_DISTRIBUTION, PROBABILITYDENSITY_VOLUME_DISTRIBUTION, validateCumulativeDistribution(), and validateProbabilityDensityDistribution().

Referenced by Calibration::setPSD(), and Material::setPSD().

◆ validateCumulativeDistribution()

void PSD::validateCumulativeDistribution ( )

Validates if a CDF starts with zero and adds up to unity.

Validates if a distribution is cumulative by first checking if the psd vector is empty and that the scaling of probabilities is in the range [0,1]. Also it checks if each consecutive value is higher than the latter value (i.e. assuming piecewise linear CDF: p_i > p_i-1). Further it replaces probabilities if the CDF does not start with zero or does not end with unity (i.e. p_0=0 and p_end=1)

214 {
215  // ensure interval of probabilities to be [0,1]
216  for (auto p = 0; p < particleSizeDistribution_.size(); ++p)
217  particleSizeDistribution_[p].probability =
218  particleSizeDistribution_[p].probability / particleSizeDistribution_.back().probability;
219  // check whether the distribution is cumulative
220  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
221  {
222  logger.assert_always(it->probability >= (it - 1)->probability,
223  "psd is not cumulative: radius % %, probabilities % %", (it - 1)->internalVariable,
224  it->internalVariable, (it - 1)->probability, it->probability);
225  }
226  // cdf needs to start with a probability of zero
227  if (particleSizeDistribution_[0].probability != 0)
228  {
229  logger(INFO, "adding a zero at the beginning of the psd");
231  {std::max(1e-3 * particleSizeDistribution_[0].internalVariable,
232  2 * particleSizeDistribution_[0].internalVariable -
233  particleSizeDistribution_[1].internalVariable), 0});
234  }
235  // cdf needs to end with a probability of one
236  if (particleSizeDistribution_.back().probability < 1)
237  {
238  logger(INFO, "adding a one at the end of the psd");
239  particleSizeDistribution_.push_back({particleSizeDistribution_.back().internalVariable, 1});
240  }
241  // cut off equal subsequent values on the end of the cdf to remove zero size classes.
242  for (auto i = particleSizeDistribution_.end() - 1; i != particleSizeDistribution_.begin(); i--)
243  {
244  if (i->probability == (i - 1)->probability)
245  {
247  .end(), i));
248  }
249  else
250  {
251  break;
252  }
253  }
254 }

References constants::i, INFO, logger, and particleSizeDistribution_.

Referenced by convertProbabilityDensityToCumulative(), setDistributionLogNormal(), setDistributionNormal(), setDistributionUniform(), setPSDFromCSV(), and setPSDFromVector().

◆ validateProbabilityDensityDistribution()

void PSD::validateProbabilityDensityDistribution ( )

Validates if the integral of the PDF equals to unity.

Validates if a PDF is valid by first checking if the PDF starts with zero (i.e. p_0=0). Further it checks if the integral is equal to unity (i.e. assuming piecewise constant PDF: sum(p_i)=1).

261 {
262  Mdouble sum = 0;
263  // check if the psd starts with zero probability (i.e. p_0=0)
264  if (particleSizeDistribution_[0].probability != 0)
265  {
266  logger(INFO, "adding a zero at the beginning of PDF");
268  {std::max(1e-3 * particleSizeDistribution_[0].internalVariable,
269  2 * particleSizeDistribution_[0].internalVariable -
270  particleSizeDistribution_[1].internalVariable), 0});
271  }
272  // sum up probabilities to check if it equals to unity (sum(p_i)=1)
273  for (auto& it : particleSizeDistribution_)
274  {
275  sum += it.probability;
276  }
277  // ensure interval of probabilities to be [0,1] by normalization.
278  for (auto& it : particleSizeDistribution_)
279  it.probability /= sum;
280  // if the sum of probabilities is not equal to unity, sum up the normalized probabilities again
281  if (sum - 1 > 1e-6)
282  {
283  sum = 0;
284  for (auto& it: particleSizeDistribution_)
285  {
286  sum += it.probability;
287  }
288  }
289  logger.assert_debug(sum - 1 < 1e-6, "PDF is not valid: Integral of PDF is not equal to unity");
290 }

References INFO, logger, and particleSizeDistribution_.

Referenced by convertCumulativeToProbabilityDensity(), setPSDFromCSV(), and setPSDFromVector().

Friends And Related Function Documentation

◆ operator< [1/2]

bool operator< ( const DistributionElements l,
const DistributionElements r 
)
friend

determines if a certain value of the PSD vector is lower than another one. Used for std::lower_bound()

Required to use std::lower_bound for finding when the probability is higher than a certain value.

Returns
TRUE if probability from a vector of type DistributionElements is higher than a certain value from a vector of type DistributionElements and FALSE in the opposite case.
1021 {
1022  return l.probability < r.probability;
1023 }
Mdouble probability
Definition: DistributionElements.h:37

◆ operator< [2/2]

bool operator< ( const DistributionElements l,
Mdouble  r 
)
friend

determines if a certain value of the PSD vector is lower than a double.

required to use std::lower_bound for finding when the probability provided as a double is higher than a certain value.

Returns
TRUE if probability as double is higher than a certain value from a DistributionElements vector and FALSE in the opposite case.
1032 {
1033  return l.probability < prob;
1034 }

◆ operator<<

std::ostream& operator<< ( std::ostream &  os,
DistributionElements p 
)
friend

Writes to output stream.

Writes to output stream. This function is used for restart files.

Returns
a reference to an output stream.
1061 {
1062  os << p.internalVariable << ' ' << p.probability << ' ';
1063  return os;
1064 }
Mdouble internalVariable
Definition: DistributionElements.h:36

◆ operator==

Mdouble operator== ( DistributionElements  l,
Mdouble  r 
)
friend

Determines if a certain value of the PSD vector is equal to a double.

Required to use std::distance to find the index of the PSD size class in which a particle has to be inserted

Returns
A double which determines the size class (radius) a particle will be inserted to.
1041 {
1042  return l.internalVariable == r;
1043 }

◆ operator>>

std::istream& operator>> ( std::istream &  is,
DistributionElements p 
)
friend

Reads from input stream.

reads from input stream. This function is used for restart files.

Returns
a reference to an input stream.
1050 {
1051  is >> p.internalVariable;
1052  is >> p.probability;
1053  return is;
1054 }

Member Data Documentation

◆ index_

int PSD::index_
private

Integer which determines the class in which a particle has to be inserted for the manual insertion routine.

Referenced by decrementNParticlesPerClass(), decrementVolumePerClass(), insertManuallyByVolume(), and PSD().

◆ nParticlesPerClass_

std::vector<int> PSD::nParticlesPerClass_
private

Vector of integers which represents the number of inserted particles in each size class. The classes in this vector are defined to contain the particles between size r_i and r_i-1. (e.g. size class 12 consists of particles between size class 12 and 11 of the PDF)

Referenced by decrementNParticlesPerClass(), getInsertedParticleNumber(), and insertManuallyByVolume().

◆ particleSizeDistribution_

◆ random_

RNG PSD::random_
private

Mercury random number generator object used to draw random numbers from a random initial seed

Referenced by drawSample(), PSD(), and setFixedSeed().

◆ volumePerClass_

std::vector<Mdouble> PSD::volumePerClass_
private

Vector of doubles which stores the volume of inserted particles for each size class. This vector is used in the insertManuallyByVolume() function to check if the volumeAllowed per class is exceeded and thus no further particles should be added to a certain class. The classes in this vector are defined to contain the volume of particles between size r_i and r_i-1. (e.g. size class 12 consists of the particles' volume between size class 12 and 11 of the PDF)

Referenced by decrementVolumePerClass(), and insertManuallyByVolume().


The documentation for this class was generated from the following files: