MercuryDPM  Trunk
PSD Class Reference

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

#include <PSD.h>

## Classes

Class which stores radii and probabilities of a PSD. This class should be used as a vector<PSD::RadiusAndProbability>. More...

## Public Types

enum  TYPE {
TYPE::CUMULATIVE_NUMBER_DISTRIBUTION, TYPE::CUMULATIVE_LENGTH_DISTRIBUTION, TYPE::CUMULATIVE_VOLUME_DISTRIBUTION, TYPE::CUMULATIVE_AREA_DISTRIBUTION,
TYPE::PROBABILITYDENSITY_NUMBER_DISTRIBUTION, TYPE::PROBABILITYDENSITY_LENGTH_DISTRIBUTION, TYPE::PROBABILITYDENSITY_AREA_DISTRIBUTION, TYPE::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 ()
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...

MERCURY_DEPRECATED void setPSDFromVector (std::vector< RadiusAndProbability > psd, TYPE PSDType)
Deprecated version of reading in PSDs from a vector. More...

read in the PSD vector with probabilities and radii saved in a .csv file. 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 percentileMin, Mdouble percentileMax, Mdouble minPolydispersity=0.1)
cutoff the PSD at given percentiles. More...

void cutoffAndSqueezeCumulative (Mdouble percentileMin, Mdouble percentileMax, Mdouble squeeze, Mdouble minPolydispersity=0.1)
cutoff the PSD at given percentiles and make it less polydisperse by squeezing it. More...

Get smallest radius of the PSD. More...

Get largest radius of the PSD. More...

Get the PSD vector. More...

int getInsertedParticleNumber ()
Get the number of particles already inserted into the simulation. More...

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

Calculate the percentile of the PSD. More...

get a volumetric mean radius of the PSD. More...

void computeRawMomenta ()
compute raw momenta of the user defined PSD. More...

void computeCentralMomenta ()
compute central momenta of the user defined PSD. More...

void computeStandardisedMomenta ()
compute standardised momenta of the user defined PSD. More...

std::array< Mdouble, 6 > getMomenta ()
get momenta of the user defined PSD. More...

## Private Attributes

std::array< Mdouble, 6 > momenta_ {}

std::vector< int > nParticlesPerClass_

std::vector< MdoublevolumePerClass_

## Friends

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

bool operator< (const PSD::RadiusAndProbability &l, Mdouble r)
determines if a certain value of the PSD vector is lower than a double. More...

std::ostream & operator<< (std::ostream &os, PSD::RadiusAndProbability &p)
Writes to output stream. More...

std::istream & operator>> (std::istream &is, PSD::RadiusAndProbability &p)

Mdouble operator== (PSD::RadiusAndProbability 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 PSD::RadiusAndProbability 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.

Definition at line 62 of file PSD.h.

## Member Enumeration Documentation

 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

Definition at line 71 of file PSD.h.

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

## Constructor & Destructor Documentation

 PSD::PSD ( )

Constructor; sets everything to 0 or default.

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

Definition at line 32 of file PSD.cc.

References momenta_.

Referenced by copy().

33 {
34  for (auto& p : momenta_)
35  p = 0;
36 }
std::array< Mdouble, 6 > momenta_
Definition: PSD.h:277
 PSD::PSD ( const PSD & other )

Copy constructor with deep copy.

Copy constructor

Definition at line 41 of file PSD.cc.

References momenta_, and particleSizeDistribution_.

42 {
44  momenta_ = other.momenta_;
45 }
std::array< Mdouble, 6 > momenta_
Definition: PSD.h:277
Definition: PSD.h:272
 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

 void PSD::computeCentralMomenta ( )

compute central momenta of the user defined PSD.

Compute the central momenta of the PSD from their respective raw momenta.

Definition at line 764 of file PSD.cc.

References computeRawMomenta(), and momenta_.

Referenced by computeStandardisedMomenta().

765 {
767  Mdouble mean = momenta_[1];
768  momenta_[5] += -5 * mean * momenta_[4] + 10 * mean * mean * momenta_[3]
769  - 10 * mean * mean * mean * momenta_[2] + 4 * mean * mean * mean * mean * mean;
770  momenta_[4] += -4 * mean * momenta_[3] + 6 * mean * mean * momenta_[2] - 3 * mean * mean * mean * mean;
771  momenta_[3] += -3 * mean * momenta_[2] + 2 * mean * mean * mean;
772  momenta_[2] += -mean * mean;
773 }
double Mdouble
Definition: GeneralDefine.h:34
std::array< Mdouble, 6 > momenta_
Definition: PSD.h:277
void computeRawMomenta()
compute raw momenta of the user defined PSD.
Definition: PSD.cc:744
 void PSD::computeRawMomenta ( )

compute raw momenta of the user defined PSD.

Compute the raw momenta of the inserted PSD by converting it to a PDF, calculating the moments m_i according to $$m_i = \sum_{j=0}^n$$ 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 Wikipedia for details.

Definition at line 744 of file PSD.cc.

Referenced by computeCentralMomenta().

745 {
747  for (size_t im = 0; im < momenta_.size(); ++im)
748  {
749  // prevent summing up of moments for each time step of the simulation
750  momenta_[im] = 0;
751  for (auto& it : particleSizeDistribution_)
752  {
753  momenta_[im] += std::pow(it.radius, im) * it.probability;
754  }
755  }
756  // zeroth-moment equals particle number for a PROBABILITYDENSITY_NUMBER_DISTRIBUTION
759 }
std::array< Mdouble, 6 > momenta_
Definition: PSD.h:277
Definition: PSD.h:272
void convertCumulativeToProbabilityDensity()
Converts a CDF to a PDF by derivation.
Definition: PSD.cc:444
int getInsertedParticleNumber()
Get the number of particles already inserted into the simulation.
Definition: PSD.cc:728
void convertProbabilityDensityToCumulative()
Converts a PDF to a CDF by integration.
Definition: PSD.cc:429
 void PSD::computeStandardisedMomenta ( )

compute standardised momenta of the user defined PSD.

Compute the standardised momenta of the PSD from their respective central momenta.

Definition at line 778 of file PSD.cc.

References computeCentralMomenta(), and momenta_.

779 {
781  Mdouble std = std::sqrt(momenta_[2]);
782  momenta_[3] /= std * std * std;
783  momenta_[4] /= std * std * std * std;
784  momenta_[5] /= std * std * std * std * std;
785 }
double Mdouble
Definition: GeneralDefine.h:34
void computeCentralMomenta()
compute central momenta of the user defined PSD.
Definition: PSD.cc:764
std::array< Mdouble, 6 > momenta_
Definition: PSD.h:277
 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] PDFType Type 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

Definition at line 551 of file PSD.cc.

552 {
553  Mdouble sum = 0;
554  switch (CDFType)
555  {
556  default:
557  logger(ERROR, "Wrong CDFType");
558  break;
560  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
561  {
563
564  // sum up probabilities
565  sum += it->probability;
566  }
567  // normalize
568  for (auto& p : particleSizeDistribution_)
569  {
570  p.probability /= sum;
571  }
572  break;
574  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
575  {
577
578  // sum up probabilities
579  sum += it->probability;
580  }
581  // normalize
582  for (auto& p : particleSizeDistribution_)
583  {
584  p.probability /= sum;
585  }
586  break;
588  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
589  {
591
592  // sum up probabilities
593  sum += it->probability;
594  }
595  // normalize
596  for (auto& p : particleSizeDistribution_)
597  {
598  p.probability /= sum;
599  }
600  break;
601  }
602 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
Definition: PSD.h:272
 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).

Definition at line 444 of file PSD.cc.

445 {
446  // subtract cumulative probabilities
447  Mdouble probabilityOld = 0, probabilityCDF;
448  for (auto& it : particleSizeDistribution_)
449  {
450  probabilityCDF = it.probability;
451  it.probability -= probabilityOld;
452  probabilityOld = probabilityCDF;
453  }
454  // check whether probability density distribution is valid
456 }
double Mdouble
Definition: GeneralDefine.h:34
void validateProbabilityDensityDistribution()
Validates if the integral of the PDF equals to unity.
Definition: PSD.cc:251
Definition: PSD.h:272
 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().

Definition at line 526 of file PSD.cc.

References particleSizeDistribution_, and mathsFunc::square().

527 {
528  Mdouble sum = 0;
529  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
530  {
531  it->probability *=
533  // old conversion
535  // sum up probabilities
536  sum += it->probability;
537  }
538  // normalize
539  for (auto& p : particleSizeDistribution_)
540  {
541  p.probability /= sum;
542  }
543 }
double Mdouble
Definition: GeneralDefine.h:34
Definition: PSD.h:272
T square(const T val)
squares a number
Definition: ExtendedMath.h:104
 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).

Definition at line 429 of file PSD.cc.

References particleSizeDistribution_, and validateCumulativeDistribution().

430 {
432  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
433  {
434  it->probability = std::min(1.0, it->probability + (it - 1)->probability);
435  }
436  // check whether cumulative distribution is valid
438 }
void validateCumulativeDistribution()
Validates if a CDF starts with zero and adds up to unity.
Definition: PSD.cc:210
Definition: PSD.h:272
 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] PDFType Type of the PDF: PROBABILITYDENSITY_LENGTH_DISTRIBUTION, PROBABILITYDENSITY_AREA_DISTRIBUTION or PROBABILITYDENSITY_VOLUME_DISTRIBUTION, Where L = Length, A = Area and V = Volume.

Definition at line 464 of file PSD.cc.

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

465 {
466  Mdouble sum = 0;
467  switch (PDFType)
468  {
469  default:
470  logger(ERROR, "Wrong PDFType");
471  break;
473  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
474  {
476  // old conversion
478  // sum up probabilities
479  sum += it->probability;
480  }
481  // normalize
482  for (auto& p : particleSizeDistribution_)
483  {
484  p.probability /= sum;
485  }
486  break;
488  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
489  {
490  it->probability /=
492  // old conversion
494  // sum up probabilities
495  sum += it->probability;
496  }
497  // normalize
498  for (auto& p : particleSizeDistribution_)
499  {
500  p.probability /= sum;
501  }
502  break;
504  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
505  {
506  it->probability /=
508  // old conversion
510  // sum up probabilities
511  sum += it->probability;
512  }
513  // normalize
514  for (auto& p : particleSizeDistribution_)
515  {
516  p.probability /= sum;
517  }
518  break;
519  }
520 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
Definition: PSD.h:272
T square(const T val)
squares a number
Definition: ExtendedMath.h:104
 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

Definition at line 59 of file PSD.cc.

References PSD().

60 {
61 #ifdef DEBUG_CONSTRUCTOR
62  std::cout << "PSD::copy() const finished" << std::endl;
63 #endif
64  return new PSD(*this);
65 }
PSD()
Constructor; sets everything to 0 or default.
Definition: PSD.cc:32
 void PSD::cutoffAndSqueezeCumulative ( Mdouble percentileMin, Mdouble percentileMax, Mdouble squeeze, Mdouble minPolydispersity = 0.1 )

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

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

Parameters
 [in] percentileMin undersize percentile to cut off the lower part of the CDF. [in] percentileMax oversize percentile to cut off the upper part of the CDF. [in] squeeze applies a squeezing factor ([0,1]) which determines the degree the PDF gets squeezed. [in] minPolydispersity applies a minimum of polydispersity ([0,1]) at the base of the CDF.

Definition at line 637 of file PSD.cc.

References cutoffCumulativeNumber(), and getDx().

639 {
640  Mdouble r50 = 0.5 * PSD::getDx(0.5);
641  // cut off
642  cutoffCumulativeNumber(percentileMin, percentileMax, minPolydispersity);
643  // squeeze psd
644  for (auto& p : particleSizeDistribution_)
645  {
647  }
648 }
double Mdouble
Definition: GeneralDefine.h:34
Mdouble getDx(Mdouble x)
Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile of the PSD.
Definition: PSD.cc:655
Definition: PSD.h:272
void cutoffCumulativeNumber(Mdouble percentileMin, Mdouble percentileMax, Mdouble minPolydispersity=0.1)
cutoff the PSD at given percentiles.
Definition: PSD.cc:610
 void PSD::cutoffCumulativeNumber ( Mdouble percentileMin, Mdouble percentileMax, Mdouble minPolydispersity = 0.1 )

cutoff the PSD at given percentiles.

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

Parameters
 [in] percentileMin undersize percentile to cut off the lower part of the CDF. [in] percentileMax oversize percentile to cut off the upper part of the CDF. [in] minPolydispersity Applies a minimum of polydispersity ([0,1]) at the base of the CDF.

Definition at line 610 of file PSD.cc.

Referenced by cutoffAndSqueezeCumulative().

611 {
614  // to get a minimum polydispersity at the base
616  // cut off min
622  // cut off max
626 }
double Mdouble
Definition: GeneralDefine.h:34
Definition: PSD.h:272
Calculate the percentile of the PSD.
Definition: PSD.cc:665
 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.
Todo:
TP: We should add a variable seed. Maybe make it definable by the user?

Definition at line 109 of file PSD.cc.

References particleSizeDistribution_.

Referenced by InsertionBoundary::generateParticle().

110 {
111  // draw a number between 0 and 1, uniformly distributed
113  static std::mt19937 gen(0);
114  static std::uniform_real_distribution<Mdouble> dist(0, 1);
115  Mdouble prob = dist(gen);
116  // find the interval [low,high] of the psd in which the number sits
117  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(), prob);
118  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
121  Mdouble pMin = low->probability;
122  Mdouble pMax = high->probability;
124  Mdouble a = (prob - pMin) / (pMax - pMin);
125  return a * rMin + (1 - a) * rMax;
126 }
double Mdouble
Definition: GeneralDefine.h:34
Definition: PSD.h:272
 Mdouble PSD::getDx ( Mdouble x )

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

Gets the diameter from a certain percentile of the PSD.

Returns
A double which is the diameter corresponding to a certain percentile.
Parameters
 [in] x double which determines the obtained diameter as a percentile of the PSD.

Definition at line 655 of file PSD.cc.

Referenced by cutoffAndSqueezeCumulative().

656 {
657  return 2.0 * getRadiusByPercentile(x / 100);
658 }
Calculate the percentile of the PSD.
Definition: PSD.cc:665
 int PSD::getInsertedParticleNumber ( )

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.

Definition at line 728 of file PSD.cc.

References nParticlesPerClass_.

Referenced by computeRawMomenta().

729 {
730  int sum = 0;
731  for (auto& it : nParticlesPerClass_)
732  sum += it;
733  return sum;
734 }
std::vector< int > nParticlesPerClass_
Definition: PSD.h:284

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.

Definition at line 709 of file PSD.cc.

710 {
712 }
Definition: PSD.h:272

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.

Definition at line 700 of file PSD.cc.

701 {
703 }
Definition: PSD.h:272
 std::array< Mdouble, 6 > PSD::getMomenta ( )

get momenta of the user defined PSD.

Get momenta of the user defined particleSizeDistribution_ vector.

Returns
Array of momenta corresponding to the first six moments of the user defined PSD.

Definition at line 791 of file PSD.cc.

References momenta_.

792 {
793  return momenta_;
794 }
std::array< Mdouble, 6 > momenta_
Definition: PSD.h:277
 std::vector< PSD::RadiusAndProbability > 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.

Definition at line 718 of file PSD.cc.

References particleSizeDistribution_.

719 {
721 }
Definition: PSD.h:272
 Mdouble PSD::getRadiusByPercentile ( Mdouble percentile )

Calculate the percentile of the PSD.

gets the radius from a certain percentile of the PSD

Returns
A double which is the radius corresponding to a certain percentile of the PSD.
Parameters
 [in] percentile double which determines the returned radius as a percentile of the PSD.

Definition at line 665 of file PSD.cc.

References logger.

Referenced by cutoffCumulativeNumber(), and getDx().

666 {
667  logger.assert_always(percentile <= 1 && percentile >= 0, "percentile is not between 0 and 1");
668  // find the percentile corresponding to the PSD
669  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(), percentile);
670  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
671  if (high->probability == low->probability)
673  else
675  (high->probability - low->probability);
676 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
Definition: PSD.h:272

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.

Definition at line 683 of file PSD.cc.

684 {
685  Mdouble mean = 0;
688  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
689  mean += it->probability * 0.5 * (cubic(it->radius) + cubic((it - 1)->radius));
690  mean = pow(mean, 1. / 3.);
693  return mean;
694 }
double Mdouble
Definition: GeneralDefine.h:34
void convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution()
convert a PROBABILITYDENSITY_NUMBER_DISTRIBUTION to a PROBABILITYDENSITY_VOLUME_DISTRIBUTION.
Definition: PSD.cc:526
T cubic(const T val)
calculates the cube of a number
Definition: ExtendedMath.h:113
Definition: PSD.h:272
void convertProbabilityDensityToProbabilityDensityNumberDistribution(TYPE PDFType)
convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION.
Definition: PSD.cc:464
void convertCumulativeToProbabilityDensity()
Converts a CDF to a PDF by derivation.
Definition: PSD.cc:444
void convertProbabilityDensityToCumulative()
Converts a PDF to a CDF by integration.
Definition: PSD.cc:429
 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] volume volume of the geometry to be filled.
Returns
A Radius for a randomly assigned probability of a specific size class.

Definition at line 137 of file PSD.cc.

Referenced by InsertionBoundary::generateParticle().

138 {
139  // initialize the particleNumberPerClass vector if empty.
140  if (nParticlesPerClass_.empty())
142  // initialize the particleNumberPerClass vector if empty.
143  if (volumePerClass_.empty())
145
146  for (auto it = particleSizeDistribution_.end() - 1; it != particleSizeDistribution_.begin(); --it)
147  {
148  static std::mt19937 gen(0);
149  static std::uniform_real_distribution<Mdouble> dist(0, 1);
150  Mdouble prob = dist(gen);
151  // map the probability to the current class interval
152  prob = (it - 1)->probability + (it->probability - (it - 1)->probability) * prob;
153  // find the interval [low,high] of the psd in which the number sits
154  auto high = std::lower_bound(particleSizeDistribution_.begin(), particleSizeDistribution_.end(), prob);
155  auto low = std::max(particleSizeDistribution_.begin(), high - 1);
158  Mdouble pMin = low->probability;
159  Mdouble pMax = high->probability;
161  int index = std::distance(particleSizeDistribution_.begin(), high);
162  Mdouble a = (prob - pMin) / (pMax - pMin);
163  Mdouble rad = a * rMin + (1 - a) * rMax;
164  // Compare inserted volume against volumeAllowed
168  Mdouble volumeAllowed = particleSizeDistribution_[index].probability * volume;
171  if (volumePerClass_[index] > volumeAllowed)
172  {
173  continue;
174  }
175  else if (radVolume + volumePerClass_[index] > volumeAllowed)
176  {
177  Mdouble differenceVolumeLow = -(volumePerClass_[index] - volumeAllowed);
178  Mdouble differenceVolumeHigh = radVolume + volumePerClass_[index] - volumeAllowed;
179  Mdouble volumeRatio = differenceVolumeLow / differenceVolumeHigh;
180  // If volumeRatio > 1 it will insert anyways, because it should be no problem for the distribution
181  prob = dist(gen);
182  if (prob <= volumeRatio)
183  {
184  ++nParticlesPerClass_[index];
187  }
188  else
189  {
190  continue;
191  }
192  }
193  else
194  {
195  ++nParticlesPerClass_[index];
198  }
199  }
200  return 0;
201 }
double Mdouble
Definition: GeneralDefine.h:34
std::vector< int > nParticlesPerClass_
Definition: PSD.h:284
void convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution()
convert a PROBABILITYDENSITY_NUMBER_DISTRIBUTION to a PROBABILITYDENSITY_VOLUME_DISTRIBUTION.
Definition: PSD.cc:526
const Mdouble pi
Definition: ExtendedMath.h:45
Definition: PSD.h:272
std::vector< Mdouble > volumePerClass_
Definition: PSD.h:293
void convertProbabilityDensityToProbabilityDensityNumberDistribution(TYPE PDFType)
convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION.
Definition: PSD.cc:464
void convertCumulativeToProbabilityDensity()
Converts a CDF to a PDF by derivation.
Definition: PSD.cc:444
void convertProbabilityDensityToCumulative()
Converts a PDF to a CDF by integration.
Definition: PSD.cc:429
 void PSD::printPSD ( )

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.

Definition at line 71 of file PSD.cc.

References particleSizeDistribution_.

72 {
74  {
75  for (const auto p : particleSizeDistribution_)
76  {
77  std::cout << p.radius << "m\t" << p.probability * 100 << "\%\n";
78  }
79  }
80  else if (particleSizeDistribution_.front().radius > 1e-4)
81  {
82  for (const auto p : particleSizeDistribution_)
83  {
84  std::cout << p.radius * 1000 << "mm\t" << p.probability * 100 << "\%\n";
85  }
86  }
87  else if (particleSizeDistribution_.front().radius > 1e-7)
88  {
89  for (const auto p : particleSizeDistribution_)
90  {
91  std::cout << p.radius * 1e6 << "um\t" << p.probability * 100 << "\%\n";
92  }
93  }
94  else
95  {
96  for (const auto p : particleSizeDistribution_)
97  {
98  std::cout << p.radius * 1e9 << "nm\t" << p.probability * 100 << "\%\n";
99  }
100  }
101 }
Definition: PSD.h:272
 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] fileName Name of the .csv file containing the radii and probabilities of the PSD. [in] PSDType Type 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] headings If 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] unitScalingFactorRadii Scaling factor of radii to match SI-units.

Definition at line 361 of file PSD.cc.

362 {
368  std::vector<Mdouble> probabilities = csv.getSecondColumn(1.0);
369  logger.assert_always(radii.size() == probabilities.size(), "The radii and probabilities vector have to be the "
370  "same size");
371  // combine radii and probabilities
372  for (int i = 0; i < radii.size(); ++i)
373  {
375  }
376  logger.assert_always(!particleSizeDistribution_.empty(), "PSD cannot be empty");
377  switch (PSDType)
378  {
379  // default case is a CUMULATIVE_NUMBER_DISTRIBUTION
380  default:
382  break;
389  break;
395  break;
402  break;
406  break;
411  break;
416  break;
421  break;
422  }
423 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
const std::complex< Mdouble > i
Definition: ExtendedMath.h:50
void validateCumulativeDistribution()
Validates if a CDF starts with zero and adds up to unity.
Definition: PSD.cc:210
void validateProbabilityDensityDistribution()
Validates if the integral of the PDF equals to unity.
Definition: PSD.cc:251
std::vector< Mdouble > getFirstColumn(Mdouble scalingFactor)
Get first column of a .csv file and return it as a double.
Definition: PSD.h:272
void convertProbabilityDensityToProbabilityDensityNumberDistribution(TYPE PDFType)
convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION.
Definition: PSD.cc:464
void convertCumulativeToProbabilityDensity()
Converts a CDF to a PDF by derivation.
Definition: PSD.cc:444
void convertProbabilityDensityToCumulative()
Converts a PDF to a CDF by integration.
Definition: PSD.cc:429
std::vector< Mdouble > getSecondColumn(Mdouble scalingFactor)
Get second column of a .csv file and return it as a double.
Enables reading of .csv files into MercuryDPM.
 void PSD::setPSDFromVector ( std::vector< RadiusAndProbability > 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] psdVector Vector containing radii and probabilities ([0,1]). [in] PSDType Type 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.
Deprecated:
This is the old way of inserting PSDs. In the future use setPSDFromCSV().

Definition at line 295 of file PSD.cc.

296 {
297  particleSizeDistribution_ = psdVector;
298  switch (PSDType)
299  {
300  // default case is a cumulative number distribution (CND)
301  default:
303  break;
310  break;
317  break;
323  break;
328  break;
332  break;
337  break;
342  break;
343  }
344 }
void validateCumulativeDistribution()
Validates if a CDF starts with zero and adds up to unity.
Definition: PSD.cc:210
void validateProbabilityDensityDistribution()
Validates if the integral of the PDF equals to unity.
Definition: PSD.cc:251
Definition: PSD.h:272
void convertProbabilityDensityToProbabilityDensityNumberDistribution(TYPE PDFType)
convert any PDF to a PROBABILITYDENSITY_NUMBER_DISTRIBUTION.
Definition: PSD.cc:464
void convertCumulativeToProbabilityDensity()
Converts a CDF to a PDF by derivation.
Definition: PSD.cc:444
void convertProbabilityDensityToCumulative()
Converts a PDF to a CDF by integration.
Definition: PSD.cc:429
 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)

Definition at line 210 of file PSD.cc.

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

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

211 {
212  // ensure interval of probabilities to be [0,1]
213  for (auto p = 0; p < particleSizeDistribution_.size(); ++p)
214  particleSizeDistribution_[p].probability =
215  particleSizeDistribution_[p].probability / particleSizeDistribution_.back().probability;
216  // check whether the distribution is cumulative
217  for (auto it = particleSizeDistribution_.begin() + 1; it != particleSizeDistribution_.end(); ++it)
218  {
219  logger.assert_always(it->probability >= (it - 1)->probability, "psd is not cumulative");
220  }
222  if (particleSizeDistribution_[0].probability != 0)
223  {
224  logger(INFO, "adding a zero at the beginning of the psd");
229  }
230  // cdf needs to end with a probability of one
231  if (particleSizeDistribution_.back().probability < 1)
232  {
233  logger(INFO, "adding a one at the end of the psd");
235  }
236  // cut off equal subsequent values on the end of the cdf to remove zero size classes.
237  for (auto i = particleSizeDistribution_.end() - 1; i != particleSizeDistribution_.begin(); i--)
238  {
239  if (i->probability == (i - 1)->probability)
240  {
242  .end(), i));
243  }
244  }
245 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
const std::complex< Mdouble > i
Definition: ExtendedMath.h:50
Definition: PSD.h:272
 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).

Definition at line 251 of file PSD.cc.

References INFO, logger, and particleSizeDistribution_.

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

252 {
253  Mdouble sum = 0;
254  // check if the psd starts with zero probability (i.e. p_0=0)
255  if (particleSizeDistribution_[0].probability != 0)
256  {
257  logger(INFO, "adding a zero at the beginning of PDF");
262  }
263  // sum up probabilities to check if it equals to unity (sum(p_i)=1)
264  for (auto& it : particleSizeDistribution_)
265  {
266  sum += it.probability;
267  }
268  // ensure interval of probabilities to be [0,1] by normalization.
269  for (auto& it : particleSizeDistribution_)
270  it.probability /= sum;
271  // if the sum of probabilities is not equal to unity, sum up the normalized probabilities again
272  if (sum - 1 > 1e-6)
273  {
274  sum = 0;
275  for (auto& it : particleSizeDistribution_)
276  {
277  sum += it.probability;
278  }
279  }
280  logger.assert(sum - 1 < 1e-6, "PDF is not valid: Integral of PDF is not equal to unity");
281 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
Definition: PSD.h:272

## Friends And Related Function Documentation

 bool operator< ( const PSD::RadiusAndProbability & l, const PSD::RadiusAndProbability & 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 PSD::RadiusAndProbability is higher than a certain value from a vector of type PSD::RadiusAndProbability and FALSE in the opposite case.

Definition at line 801 of file PSD.cc.

802 {
803  return l.probability < r.probability;
804 }
Mdouble probability
Definition: PSD.h:90
 bool operator< ( const PSD::RadiusAndProbability & 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 PSD::RadiusAndProbability vector and FALSE in the opposite case.

Definition at line 812 of file PSD.cc.

813 {
814  return l.probability < prob;
815 }
Mdouble probability
Definition: PSD.h:90
 std::ostream& operator<< ( std::ostream & os, PSD::RadiusAndProbability & p )
friend

Writes to output stream.

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

Returns
a reference to an output stream.

Definition at line 841 of file PSD.cc.

842 {
843  os << p.radius << ' ' << p.probability << ' ';
844  return os;
845 }
Mdouble probability
Definition: PSD.h:90
 Mdouble operator== ( PSD::RadiusAndProbability 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.

Definition at line 821 of file PSD.cc.

822 {
824 }
 std::istream& operator>> ( std::istream & is, PSD::RadiusAndProbability & p )
friend

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

Returns
a reference to an input stream.

Definition at line 830 of file PSD.cc.

831 {
833  is >> p.probability;
834  return is;
835 }
Mdouble probability
Definition: PSD.h:90

## Member Data Documentation

 std::array PSD::momenta_ {}
private

Array of doubles which stores the moments of a user defined discrete PROBABILITYDENSITY_NUMBER_DISTRIBUTION.

Definition at line 277 of file PSD.h.

Referenced by computeCentralMomenta(), computeRawMomenta(), computeStandardisedMomenta(), getMomenta(), and PSD().

 std::vector 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)

Definition at line 284 of file PSD.h.

Referenced by getInsertedParticleNumber(), and insertManuallyByVolume().

 std::vector PSD::particleSizeDistribution_
private

Vector of the PSD::RadiusAndProbability class which stores radii and probabilities of the PSD.

Definition at line 272 of file PSD.h.

 std::vector 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)

Definition at line 293 of file PSD.h.

Referenced by insertManuallyByVolume().

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