PSDContinuous Struct Reference

#include <PSDContinuous.h>

Public Member Functions

bool operator< (const double probability) const
 

Static Public Member Functions

static void print (std::vector< PSDContinuous > &psd)
 
static void validateCumulativeDistribution (std::vector< PSDContinuous > &psd)
 
static std::vector< PSDContinuouscreatePSDFromRadiiAndProbabilities (const std::vector< double > &radius, const std::vector< double > &probability)
 
static void convertSubtractiveToCumulative (std::vector< PSDContinuous > &psd)
 
static void convertCumulativeToSubtractive (std::vector< PSDContinuous > &psd)
 
static void convertSubtractiveVolumeToNumber (std::vector< PSDContinuous > &psd)
 
static void convertCumulativeVolumeToNumber (std::vector< PSDContinuous > &psd)
 
static void interpolateCSD (std::vector< PSDContinuous > &psd, unsigned n)
 
static std::vector< PSDContinuousgetCumulativeNumberFromVolume (std::vector< PSDContinuous > psd)
 
static std::vector< PSDContinuouscutoffCumulativeNumber (std::vector< PSDContinuous > psd, double quantileMin, double quantileMax, double minPolydispersity=0.1)
 
static std::vector< PSDContinuouscutoffAndSqueezeCumulativeNumber (std::vector< PSDContinuous > psd, double quantileMin, double quantileMax, double squeeze, double minPolydispersity=0.1)
 
static void convertSubtractiveNumberToVolume (std::vector< PSDContinuous > &psd)
 
static void convertCumulativeNumberToVolume (std::vector< PSDContinuous > &psd)
 
static double getD0 (const std::vector< PSDContinuous > &psd)
 
static double getD10 (const std::vector< PSDContinuous > &psd)
 
static double getD50 (const std::vector< PSDContinuous > &psd)
 
static double getD90 (const std::vector< PSDContinuous > &psd)
 
static double getD100 (const std::vector< PSDContinuous > &psd)
 
static double getQuantile (std::vector< PSDContinuous > psd, double quantile)
 
static double getVolumetricMean (std::vector< PSDContinuous > psd)
 

Public Attributes

double radius
 
double probability
 

Friends

std::ostream & operator<< (std::ostream &os, const PSDContinuous &psd)
 Writes to output stream. More...
 
std::istream & operator>> (std::istream &is, PSDContinuous &psd)
 Reads from input stream. More...
 

Detailed Description

Stores a radius and a cumulative number density: To be used as a vector, std::vector<PSDContinuous> psd

Cumulative number density: nc_i is the number fraction of particles whose radius is less than r_i. It requires vc_0=0, vc_end=1. This variable is used as psd in MercuryDPM, as it can be interpreted as the probability that a particle's radius is is less than r_i: p(r<r_i) = nc_i.

Cumulative volume density: vc_i is the volume fraction of particles whose radius is less than r_i. It requires vc_0=0, vc_end=1

Subtractive volume density: v_i is the volume fraction of particles whose radius is between r_i-1 and r_i. It requires v_0=0, sum(v_i)=1

Sieve data: s_i is the volume fraction of particles whose radius is between r_i and r_i+1. It requires sum(s_i)=1. Property: s_i = v_i-1

Todo:
Make an object storing a vector of these values.

Member Function Documentation

◆ convertCumulativeNumberToVolume()

void PSDContinuous::convertCumulativeNumberToVolume ( std::vector< PSDContinuous > &  psd)
static
169  {
173 }
static void convertSubtractiveToCumulative(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:86
static void convertSubtractiveNumberToVolume(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:151
static void convertCumulativeToSubtractive(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:98

References convertCumulativeToSubtractive(), convertSubtractiveNumberToVolume(), and convertSubtractiveToCumulative().

Referenced by cutoffAndSqueezeCumulativeNumber(), cutoffCumulativeNumber(), and getQuantile().

◆ convertCumulativeToSubtractive()

void PSDContinuous::convertCumulativeToSubtractive ( std::vector< PSDContinuous > &  psd)
static
98  {
99  //subtract cumulative probabilities
100  //double v = psd[1].probability - psd[0].probability;
101  double vcOld=0, vc;
102  for (auto it=psd.begin(); it!=psd.end(); ++it) {
103  vc = it->probability;
104  it->probability -= vcOld;
105  vcOld = vc;
106  }
107 }

Referenced by convertCumulativeNumberToVolume(), convertCumulativeVolumeToNumber(), and getVolumetricMean().

◆ convertCumulativeVolumeToNumber()

void PSDContinuous::convertCumulativeVolumeToNumber ( std::vector< PSDContinuous > &  psd)
static

◆ convertSubtractiveNumberToVolume()

void PSDContinuous::convertSubtractiveNumberToVolume ( std::vector< PSDContinuous > &  psd)
static
Todo:
should this be:
151  {
152  logger.assert_always(psd[0].probability==0,"psd has to start with zero");
153  //subtract cumulative probabilities
154  double sum=0;
155  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
157  //const Mdouble R = it->radius;
158  //const Mdouble r = (it - 1)->radius;
159  //it->probability *= R*R*R*R-r*r*r*r;
160  it->probability *= 0.25 * (square(it->radius) + square((it - 1)->radius)) * (it->radius + (it - 1)->radius);
161  sum += it->probability;
162  }
163  for (auto& p : psd) {
164  p.probability /= sum;
165  }
166 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
T square(const T val)
squares a number
Definition: ExtendedMath.h:106
double probability
Definition: PSDContinuous.h:203
double radius
Definition: PSDContinuous.h:202

References logger, probability, radius, and mathsFunc::square().

Referenced by convertCumulativeNumberToVolume().

◆ convertSubtractiveToCumulative()

void PSDContinuous::convertSubtractiveToCumulative ( std::vector< PSDContinuous > &  psd)
static
86  {
87  //add up probabilities
88  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
89  it->probability = std::min(1.0, it->probability + (it-1)->probability);
90  }
91  //check whether cumulative distribution adds up to one
92  logger.assert_debug(fabs(psd.back().probability-1)<1e-12,"cumulative distribution needs to add up to one");
93  //remove rounding errors
94  psd.back().probability=1;
95 }

References logger.

Referenced by convertCumulativeNumberToVolume(), and convertCumulativeVolumeToNumber().

◆ convertSubtractiveVolumeToNumber()

void PSDContinuous::convertSubtractiveVolumeToNumber ( std::vector< PSDContinuous > &  psd)
static
Todo:
should this be:
110  {
111  logger.assert_always(psd[0].probability==0,"psd has to start with zero");
112  //subtract cumulative probabilities
113  double sum=0;
114  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
116  // const Mdouble R = it->radius;
117  // const Mdouble r = (it - 1)->radius;
118  // it->probability = R==r ? 0 : it->probability/(R*R*R*R-r*r*r*r);
119  it->probability /= 0.25*(square(it->radius)+square((it-1)->radius))*(it->radius+(it-1)->radius);
120  sum += it->probability;
121  }
122  for (auto& p : psd) {
123  p.probability /= sum;
124  }
125 }

References logger, probability, radius, and mathsFunc::square().

Referenced by convertCumulativeVolumeToNumber().

◆ createPSDFromRadiiAndProbabilities()

std::vector< PSDContinuous > PSDContinuous::createPSDFromRadiiAndProbabilities ( const std::vector< double > &  radius,
const std::vector< double > &  probability 
)
static
69  {
70  logger.assert_always(radius.size()==probability.size(),"Number of radius and probability values don't match");
71  std::vector<PSDContinuous> psd;
72 // psd.reserve(radius.size());
73 // for (int i = 0; i < radius.size(); ++i) {
74 // psd.push_back({radius[i],probability[i]});
75 // }
76  psd.reserve(radius.size()+1);
77  psd.push_back({radius.front(),0});
78  for (int i = 1; i < radius.size(); ++i) {
79  psd.push_back({radius[i],probability[i-1]});
80  }
81  psd.push_back({radius.back(),probability.back()});
82  return psd;
83 }
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References constants::i, logger, probability, and radius.

◆ cutoffAndSqueezeCumulativeNumber()

static std::vector<PSDContinuous> PSDContinuous::cutoffAndSqueezeCumulativeNumber ( std::vector< PSDContinuous psd,
double  quantileMin,
double  quantileMax,
double  squeeze,
double  minPolydispersity = 0.1 
)
inlinestatic
119  {
120  double r50 = 0.5*PSDContinuous::getD50(psd);
121  //cut off
122  psd = cutoffCumulativeNumber (psd, quantileMin, quantileMax, minPolydispersity);
123  //convert to volume psd
125  //squeeze psd
126  for (auto& p : psd) {
127  p.radius = r50+(p.radius-r50)*squeeze;
128  }
129  //convert to number psd
131  return psd;
132  }
static void convertCumulativeVolumeToNumber(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:128
static void convertCumulativeNumberToVolume(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:169
static std::vector< PSDContinuous > cutoffCumulativeNumber(std::vector< PSDContinuous > psd, double quantileMin, double quantileMax, double minPolydispersity=0.1)
Definition: PSDContinuous.h:98
static double getD50(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:154

References convertCumulativeNumberToVolume(), convertCumulativeVolumeToNumber(), cutoffCumulativeNumber(), and getD50().

◆ cutoffCumulativeNumber()

static std::vector<PSDContinuous> PSDContinuous::cutoffCumulativeNumber ( std::vector< PSDContinuous psd,
double  quantileMin,
double  quantileMax,
double  minPolydispersity = 0.1 
)
inlinestatic
98  {
99  double radiusMin = getQuantile(psd,quantileMin);
100  double radiusMax = getQuantile(psd,quantileMax);
101  //to get a minimum polydispersity at the base
102  double radiusMinCut = std::min(radiusMin*(1+minPolydispersity),radiusMax);
103  //convert to volume psd
105  //cut off min
106  while (psd.front().radius<=radiusMinCut) psd.erase(psd.begin());
107  psd.insert(psd.begin(),PSDContinuous{radiusMinCut,quantileMin});
108  psd.insert(psd.begin(),PSDContinuous{radiusMin,0});
109  //cut off max
110  while (psd.back().radius>=radiusMax) psd.pop_back();
111  psd.push_back(PSDContinuous{radiusMax,quantileMax});
112  psd.push_back(PSDContinuous{radiusMax,1});
113  //convert to number psd
115  return psd;
116  }
Definition: PSDContinuous.h:51
static double getQuantile(std::vector< PSDContinuous > psd, double quantile)
Definition: PSDContinuous.cc:188

References convertCumulativeNumberToVolume(), convertCumulativeVolumeToNumber(), and getQuantile().

Referenced by cutoffAndSqueezeCumulativeNumber().

◆ getCumulativeNumberFromVolume()

static std::vector<PSDContinuous> PSDContinuous::getCumulativeNumberFromVolume ( std::vector< PSDContinuous psd)
inlinestatic
92  {
94  return psd;
95  }

References convertCumulativeVolumeToNumber().

◆ getD0()

static double PSDContinuous::getD0 ( const std::vector< PSDContinuous > &  psd)
inlinestatic
146  {
147  return 2.0*getQuantile(psd,0.0);
148  }

References getQuantile().

◆ getD10()

static double PSDContinuous::getD10 ( const std::vector< PSDContinuous > &  psd)
inlinestatic
150  {
151  return 2.0*getQuantile(psd,0.1);
152  }

References getQuantile().

◆ getD100()

static double PSDContinuous::getD100 ( const std::vector< PSDContinuous > &  psd)
inlinestatic
162  {
163  return 2.0*getQuantile(psd,1.0);
164  }

References getQuantile().

◆ getD50()

static double PSDContinuous::getD50 ( const std::vector< PSDContinuous > &  psd)
inlinestatic
154  {
155  return 2.0*getQuantile(psd,0.5);
156  }

References getQuantile().

Referenced by cutoffAndSqueezeCumulativeNumber().

◆ getD90()

static double PSDContinuous::getD90 ( const std::vector< PSDContinuous > &  psd)
inlinestatic
158  {
159  return 2.0*getQuantile(psd,0.9);
160  }

References getQuantile().

◆ getQuantile()

double PSDContinuous::getQuantile ( std::vector< PSDContinuous psd,
double  quantile 
)
static
188  {
189  logger.assert_always(quantile<=1 && quantile>=0,"quantile is not between 0 and 1");
191  auto high = std::lower_bound(psd.begin(),psd.end(),quantile);
192  auto low = std::max(psd.begin(),high-1);
193  if (high->probability==low->probability)
194  return high->radius;
195  else
196  return low->radius + (high->radius-low->radius)*(quantile-low->probability)/(high->probability-low->probability);
197 }

References convertCumulativeNumberToVolume(), and logger.

Referenced by cutoffCumulativeNumber(), getD0(), getD10(), getD100(), getD50(), and getD90().

◆ getVolumetricMean()

double PSDContinuous::getVolumetricMean ( std::vector< PSDContinuous psd)
static
200  {
202  double mean =0;
203  for (auto it=psd.begin()+1; it!=psd.end(); ++it)
204  mean += it->probability * 0.5*(cubic(it->radius)+cubic((it-1)->radius));
205  mean = pow(mean,1./3.);
206  return mean;
207 }
T cubic(const T val)
calculates the cube of a number
Definition: ExtendedMath.h:115

References convertCumulativeToSubtractive(), mathsFunc::cubic(), and radius.

◆ interpolateCSD()

void PSDContinuous::interpolateCSD ( std::vector< PSDContinuous > &  psd,
unsigned  n 
)
static
134  {
135  std::vector<PSDContinuous> psd2;
136  for (int i = 0; i < psd.size()-1; ++i) {
137  const double r0 = psd[i].radius;
138  const double dr = psd[i+1].radius-psd[i].radius;
139  const double p0 = psd[i].probability;
140  const double dp = psd[i+1].probability-psd[i].probability;
141  for (double j = 0; j < n; ++j) {
142  psd2.push_back({r0+j/n*dr,p0+j/n*dp});
143  }
144  }
145  psd2.push_back(psd.back());
146  psd = psd2;
147 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32

References constants::i, and n.

◆ operator<()

bool PSDContinuous::operator< ( const double  probability) const
inline

required to use std::lower_bound for finding when the probability is higher than a certain value std::vector<PSDContinuous> psd; double probability; std::lower_bound(psd.begin(),psd.end(),probability);

Parameters
probability
Returns
182  {
183  return this->probability < probability;
184  }

References probability.

◆ print()

void PSDContinuous::print ( std::vector< PSDContinuous > &  psd)
static
32  {
33  if (psd.front().radius>1e-1) {
34  for (const auto p : psd) {
35  std::cout << p.radius << "m\t" << p.probability * 100 << "\%\n";
36  }
37  } else if (psd.front().radius>1e-4) {
38  for (const auto p : psd) {
39  std::cout << p.radius * 1000 << "mm\t" << p.probability * 100 << "\%\n";
40  }
41  } else {
42  for (const auto p : psd) {
43  std::cout << p.radius * 1e6 << "um\t" << p.probability * 100 << "\%\n";
44  }
45  }
46 }

◆ validateCumulativeDistribution()

void PSDContinuous::validateCumulativeDistribution ( std::vector< PSDContinuous > &  psd)
static
49  {
50  logger.assert_always(psd.size()>0,"psd vector is empty");
51  //check whether the distribution is cumulative
52  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
53  logger.assert_always(it->probability >= (it-1)->probability,"psd is not cumulative");
54  }
55  //psd needs to start with a probability of zero
56  if (psd[0].probability!=0) {
57 // logger(INFO,"adding a zero at teh beginning of the psd");
58  psd.insert(psd.begin(),{psd[0].radius,0});
59  }
60  //psd needs to end with a probability of one
61  if (psd.back().probability<1) {
62  logger(INFO,"adding a one at the end of the psd");
63  psd.push_back({psd.back().radius,1});
64  }
65 }
@ INFO

References INFO, logger, probability, and radius.

Friends And Related Function Documentation

◆ operator<<

std::ostream& operator<< ( std::ostream &  os,
const PSDContinuous psd 
)
friend

Writes to output stream.

189  {
190  os << psd.radius << ' ' << psd.probability;
191  return os;
192  }

◆ operator>>

std::istream& operator>> ( std::istream &  is,
PSDContinuous psd 
)
friend

Reads from input stream.

197  {
198  is >> psd.radius >> psd.probability;
199  return is;
200  }

Member Data Documentation

◆ probability

◆ radius


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