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
148  {
152 }
static void convertSubtractiveToCumulative(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:65
static void convertSubtractiveNumberToVolume(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:130
static void convertCumulativeToSubtractive(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:77

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

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

◆ convertCumulativeToSubtractive()

void PSDContinuous::convertCumulativeToSubtractive ( std::vector< PSDContinuous > &  psd)
static
77  {
78  //subtract cumulative probabilities
79  //double v = psd[1].probability - psd[0].probability;
80  double vcOld=0, vc;
81  for (auto it=psd.begin(); it!=psd.end(); ++it) {
82  vc = it->probability;
83  it->probability -= vcOld;
84  vcOld = vc;
85  }
86 }

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:
130  {
131  logger.assert_always(psd[0].probability==0,"psd has to start with zero");
132  //subtract cumulative probabilities
133  double sum=0;
134  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
136  //const Mdouble R = it->radius;
137  //const Mdouble r = (it - 1)->radius;
138  //it->probability *= R*R*R*R-r*r*r*r;
139  it->probability *= 0.25 * (square(it->radius) + square((it - 1)->radius)) * (it->radius + (it - 1)->radius);
140  sum += it->probability;
141  }
142  for (auto& p : psd) {
143  p.probability /= sum;
144  }
145 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
float * p
Definition: Tutorial_Map_using.cpp:9
squared absolute sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2 square(power 2)
double probability
Definition: PSDContinuous.h:182
double radius
Definition: PSDContinuous.h:181

References logger, p, probability, radius, and Eigen::square().

Referenced by convertCumulativeNumberToVolume().

◆ convertSubtractiveToCumulative()

void PSDContinuous::convertSubtractiveToCumulative ( std::vector< PSDContinuous > &  psd)
static
65  {
66  //add up probabilities
67  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
68  it->probability = std::min(1.0, it->probability + (it-1)->probability);
69  }
70  //check whether cumulative distribution adds up to one
71  logger.assert_debug(fabs(psd.back().probability-1)<1e-12,"cumulative distribution needs to add up to one");
72  //remove rounding errors
73  psd.back().probability=1;
74 }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
#define min(a, b)
Definition: datatypes.h:22
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117

References e(), boost::multiprecision::fabs(), logger, and min.

Referenced by convertCumulativeNumberToVolume(), and convertCumulativeVolumeToNumber().

◆ convertSubtractiveVolumeToNumber()

void PSDContinuous::convertSubtractiveVolumeToNumber ( std::vector< PSDContinuous > &  psd)
static
Todo:
should this be:
89  {
90  logger.assert_always(psd[0].probability==0,"psd has to start with zero");
91  //subtract cumulative probabilities
92  double sum=0;
93  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
95  // const Mdouble R = it->radius;
96  // const Mdouble r = (it - 1)->radius;
97  // it->probability = R==r ? 0 : it->probability/(R*R*R*R-r*r*r*r);
98  it->probability /= 0.25*(square(it->radius)+square((it-1)->radius))*(it->radius+(it-1)->radius);
99  sum += it->probability;
100  }
101  for (auto& p : psd) {
102  p.probability /= sum;
103  }
104 }

References logger, p, probability, radius, and Eigen::square().

Referenced by convertCumulativeVolumeToNumber().

◆ createPSDFromRadiiAndProbabilities()

std::vector< PSDContinuous > PSDContinuous::createPSDFromRadiiAndProbabilities ( const std::vector< double > &  radius,
const std::vector< double > &  probability 
)
static
48  {
49  logger.assert_always(radius.size()==probability.size(),"Number of radius and probability values don't match");
50  std::vector<PSDContinuous> psd;
51 // psd.reserve(radius.size());
52 // for (int i = 0; i < radius.size(); ++i) {
53 // psd.push_back({radius[i],probability[i]});
54 // }
55  psd.reserve(radius.size()+1);
56  psd.push_back({radius.front(),0});
57  for (int i = 1; i < radius.size(); ++i) {
58  psd.push_back({radius[i],probability[i-1]});
59  }
60  psd.push_back({radius.back(),probability.back()});
61  return psd;
62 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9

References 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
98  {
99  double r50 = 0.5*PSDContinuous::getD50(psd);
100  //cut off
101  psd = cutoffCumulativeNumber (psd, quantileMin, quantileMax, minPolydispersity);
102  //convert to volume psd
104  //squeeze psd
105  for (auto& p : psd) {
106  p.radius = r50+(p.radius-r50)*squeeze;
107  }
108  //convert to number psd
110  return psd;
111  }
static void convertCumulativeVolumeToNumber(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:107
static void convertCumulativeNumberToVolume(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:148
static std::vector< PSDContinuous > cutoffCumulativeNumber(std::vector< PSDContinuous > psd, double quantileMin, double quantileMax, double minPolydispersity=0.1)
Definition: PSDContinuous.h:77
static double getD50(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:133

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

◆ cutoffCumulativeNumber()

static std::vector<PSDContinuous> PSDContinuous::cutoffCumulativeNumber ( std::vector< PSDContinuous psd,
double  quantileMin,
double  quantileMax,
double  minPolydispersity = 0.1 
)
inlinestatic
77  {
78  double radiusMin = getQuantile(psd,quantileMin);
79  double radiusMax = getQuantile(psd,quantileMax);
80  //to get a minimum polydispersity at the base
81  double radiusMinCut = std::min(radiusMin*(1+minPolydispersity),radiusMax);
82  //convert to volume psd
84  //cut off min
85  while (psd.front().radius<=radiusMinCut) psd.erase(psd.begin());
86  psd.insert(psd.begin(),PSDContinuous{radiusMinCut,quantileMin});
87  psd.insert(psd.begin(),PSDContinuous{radiusMin,0});
88  //cut off max
89  while (psd.back().radius>=radiusMax) psd.pop_back();
90  psd.push_back(PSDContinuous{radiusMax,quantileMax});
91  psd.push_back(PSDContinuous{radiusMax,1});
92  //convert to number psd
94  return psd;
95  }
Definition: PSDContinuous.h:30
static double getQuantile(std::vector< PSDContinuous > psd, double quantile)
Definition: PSDContinuous.cc:167

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

Referenced by cutoffAndSqueezeCumulativeNumber().

◆ getCumulativeNumberFromVolume()

static std::vector<PSDContinuous> PSDContinuous::getCumulativeNumberFromVolume ( std::vector< PSDContinuous psd)
inlinestatic
71  {
73  return psd;
74  }

References convertCumulativeVolumeToNumber().

◆ getD0()

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

References getQuantile().

◆ getD10()

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

References getQuantile().

◆ getD100()

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

References getQuantile().

◆ getD50()

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

References getQuantile().

Referenced by cutoffAndSqueezeCumulativeNumber().

◆ getD90()

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

References getQuantile().

◆ getQuantile()

double PSDContinuous::getQuantile ( std::vector< PSDContinuous psd,
double  quantile 
)
static
167  {
168  logger.assert_always(quantile<=1 && quantile>=0,"quantile is not between 0 and 1");
170  auto high = std::lower_bound(psd.begin(),psd.end(),quantile);
171  auto low = std::max(psd.begin(),high-1);
172  if (high->probability==low->probability)
173  return high->radius;
174  else
175  return low->radius + (high->radius-low->radius)*(quantile-low->probability)/(high->probability-low->probability);
176 }
#define max(a, b)
Definition: datatypes.h:23

References convertCumulativeNumberToVolume(), logger, and max.

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

◆ getVolumetricMean()

double PSDContinuous::getVolumetricMean ( std::vector< PSDContinuous psd)
static
179  {
181  double mean =0;
182  for (auto it=psd.begin()+1; it!=psd.end(); ++it)
183  mean += it->probability * 0.5*(cubic(it->radius)+cubic((it-1)->radius));
184  mean = pow(mean,1./3.);
185  return mean;
186 }
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
T cubic(const T val)
calculates the cube of a number
Definition: ExtendedMath.h:95

References convertCumulativeToSubtractive(), mathsFunc::cubic(), Eigen::bfloat16_impl::pow(), and radius.

◆ interpolateCSD()

void PSDContinuous::interpolateCSD ( std::vector< PSDContinuous > &  psd,
unsigned  n 
)
static
113  {
114  std::vector<PSDContinuous> psd2;
115  for (int i = 0; i < psd.size()-1; ++i) {
116  const double r0 = psd[i].radius;
117  const double dr = psd[i+1].radius-psd[i].radius;
118  const double p0 = psd[i].probability;
119  const double dp = psd[i+1].probability-psd[i].probability;
120  for (double j = 0; j < n; ++j) {
121  psd2.push_back({r0+j/n*dr,p0+j/n*dp});
122  }
123  }
124  psd2.push_back(psd.back());
125  psd = psd2;
126 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Vector3f p0
Definition: MatrixBase_all.cpp:2
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References i, j, n, and p0.

◆ 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
161  {
162  return this->probability < probability;
163  }

References probability.

◆ print()

void PSDContinuous::print ( std::vector< PSDContinuous > &  psd)
static
11  {
12  if (psd.front().radius>1e-1) {
13  for (const auto p : psd) {
14  std::cout << p.radius << "m\t" << p.probability * 100 << "\%\n";
15  }
16  } else if (psd.front().radius>1e-4) {
17  for (const auto p : psd) {
18  std::cout << p.radius * 1000 << "mm\t" << p.probability * 100 << "\%\n";
19  }
20  } else {
21  for (const auto p : psd) {
22  std::cout << p.radius * 1e6 << "um\t" << p.probability * 100 << "\%\n";
23  }
24  }
25 }

References e(), and p.

◆ validateCumulativeDistribution()

void PSDContinuous::validateCumulativeDistribution ( std::vector< PSDContinuous > &  psd)
static
28  {
29  logger.assert_always(psd.size()>0,"psd vector is empty");
30  //check whether the distribution is cumulative
31  for (auto it=psd.begin()+1; it!=psd.end(); ++it) {
32  logger.assert_always(it->probability >= (it-1)->probability,"psd is not cumulative");
33  }
34  //psd needs to start with a probability of zero
35  if (psd[0].probability!=0) {
36 // logger(INFO,"adding a zero at teh beginning of the psd");
37  psd.insert(psd.begin(),{psd[0].radius,0});
38  }
39  //psd needs to end with a probability of one
40  if (psd.back().probability<1) {
41  logger(INFO,"adding a one at the end of the psd");
42  psd.push_back({psd.back().radius,1});
43  }
44 }
@ 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.

168  {
169  os << psd.radius << ' ' << psd.probability;
170  return os;
171  }

◆ operator>>

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

Reads from input stream.

176  {
177  is >> psd.radius >> psd.probability;
178  return is;
179  }

Member Data Documentation

◆ probability

◆ radius


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