PSDContinuous.h
Go to the documentation of this file.
1 //Copyright (c) 2013-2023, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #ifndef MERCURYDPM_PSDCONTINUOUS_H
27 #define MERCURYDPM_PSDCONTINUOUS_H
28 
29 #include <fstream>
30 #include <vector>
31 #include "iostream"
32 #include "PSD.h"
33 
51 {
52 // // sets the psd from the probability values given in the file batch_materials_PSD.xlsx
53 // static void checkPSD (std::vector<PSDContinuous>& psd) {
54 // if (psd.empty()) {
55 // logger(ERROR,"psd is empty");
56 // }
57 // if (psd[0].probability!=0) {
58 // logger(WARN,"psd should start with a zero probability");
59 // psd.emplace(psd.begin(),PSDContinuous{psd[0].radius,0});
60 // }
61 // if (psd.back().probability!=1) {
62 // logger(WARN,"psd should end with a unit probability");
63 // psd.emplace_back(PSDContinuous{psd.back().radius,1});
64 // }
65 // }
66 
67  static void print (std::vector<PSDContinuous>& psd);
68 
69  // validate whether psd is a cumulative distribution
70  static void validateCumulativeDistribution (std::vector<PSDContinuous>& psd);
71 
72  // combine vectors of radii and probabilities into psd vector
73  static std::vector<PSDContinuous> createPSDFromRadiiAndProbabilities (const std::vector<double>& radius,
74  const std::vector<double>& probability);
75 
76  // converts a subtractive to a cumulative psd
77  static void convertSubtractiveToCumulative (std::vector<PSDContinuous>& psd);
78 
79  // converst a single to a cumulative psd
80  static void convertCumulativeToSubtractive (std::vector<PSDContinuous>& psd);
81 
82  // converts a subtractive number psd to a subtractive volume psd
83  static void convertSubtractiveVolumeToNumber (std::vector<PSDContinuous>& psd);
84 
85  // converts a cumulative number psd to a cumulative volume psd
86  static void convertCumulativeVolumeToNumber (std::vector<PSDContinuous>& psd);
87 
88  // interpolates the psd linearly
89  static void interpolateCSD (std::vector<PSDContinuous>& psd, unsigned n);
90 
91  // converts a cumulative number psd to a cumulative volume psd and returns
92  static std::vector<PSDContinuous> getCumulativeNumberFromVolume (std::vector<PSDContinuous> psd) {
94  return psd;
95  }
96 
97  //cuts off at given quantiles
98  static std::vector<PSDContinuous> cutoffCumulativeNumber (std::vector<PSDContinuous> psd, double quantileMin, double quantileMax, double minPolydispersity = 0.1) {
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  }
117 
118  //cuts off at given quantiles
119  static std::vector<PSDContinuous> cutoffAndSqueezeCumulativeNumber (std::vector<PSDContinuous> psd, double quantileMin, double quantileMax, double squeeze, double minPolydispersity = 0.1) {
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  }
133 
134  // converts a subtractive number psd to a subtractive volume psd
135  static void convertSubtractiveNumberToVolume (std::vector<PSDContinuous>& psd);
136 
137  // converts a cumulative number psd to a cumulative volume psd
138  static void convertCumulativeNumberToVolume (std::vector<PSDContinuous>& psd);
139 
140 // // returns a cumulative number particle size distribution from a given volume particle size distribution
141 // static std::vector<PSDContinuous> setFromVolumePSD (const std::vector<double>& radius,
142 // const std::vector<double>& probability);
143 
144  // get quantile size
145  //todo the D0 and D100 should be fixed.
146  static double getD0 (const std::vector<PSDContinuous>& psd){
147  return 2.0*getQuantile(psd,0.0);
148  }
149 
150  static double getD10 (const std::vector<PSDContinuous>& psd){
151  return 2.0*getQuantile(psd,0.1);
152  }
153 
154  static double getD50 (const std::vector<PSDContinuous>& psd){
155  return 2.0*getQuantile(psd,0.5);
156  }
157 
158  static double getD90 (const std::vector<PSDContinuous>& psd){
159  return 2.0*getQuantile(psd,0.9);
160  }
161 
162  static double getD100 (const std::vector<PSDContinuous>& psd){
163  return 2.0*getQuantile(psd,1.0);
164  }
165 
166 
167  // get quantile of volume distribution, e.g. 2.0*getQuantile(psd,0.5) gets D50
168  static double getQuantile(std::vector<PSDContinuous> psd, double quantile);
169 
170  // get radius r such that a monodisperse system has the same number of particles as a polydisperse system
171  static double getVolumetricMean(std::vector<PSDContinuous> psd);
172 
181  bool operator<(const double probability) const
182  {
183  return this->probability < probability;
184  }
185 
189  friend std::ostream& operator<<(std::ostream& os, const PSDContinuous& psd) {
190  os << psd.radius << ' ' << psd.probability;
191  return os;
192  }
193 
197  friend std::istream& operator>>(std::istream& is, PSDContinuous& psd) {
198  is >> psd.radius >> psd.probability;
199  return is;
200  }
201 
202  double radius;
203  double probability;
204 };
205 
206 const PSD convertPSD2ToPSD(const std::vector<PSDContinuous>& psd2);
207 #endif //MERCURYDPM_PSD_H
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
const PSD convertPSD2ToPSD(const std::vector< PSDContinuous > &psd2)
Definition: PSDContinuous.cc:209
Contains a vector with radii and probabilities of a user defined particle size distribution (PSD)
Definition: PSD.h:65
Definition: PSDContinuous.h:51
static void convertSubtractiveToCumulative(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:86
friend std::ostream & operator<<(std::ostream &os, const PSDContinuous &psd)
Writes to output stream.
Definition: PSDContinuous.h:189
bool operator<(const double probability) const
Definition: PSDContinuous.h:181
static double getD0(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:146
static void convertSubtractiveVolumeToNumber(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:110
static std::vector< PSDContinuous > getCumulativeNumberFromVolume(std::vector< PSDContinuous > psd)
Definition: PSDContinuous.h:92
static double getD90(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:158
static void convertCumulativeVolumeToNumber(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:128
static void convertSubtractiveNumberToVolume(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:151
static void validateCumulativeDistribution(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:49
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 getVolumetricMean(std::vector< PSDContinuous > psd)
Definition: PSDContinuous.cc:200
static std::vector< PSDContinuous > cutoffAndSqueezeCumulativeNumber(std::vector< PSDContinuous > psd, double quantileMin, double quantileMax, double squeeze, double minPolydispersity=0.1)
Definition: PSDContinuous.h:119
static double getD10(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:150
static void convertCumulativeToSubtractive(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:98
static double getQuantile(std::vector< PSDContinuous > psd, double quantile)
Definition: PSDContinuous.cc:188
double probability
Definition: PSDContinuous.h:203
static void interpolateCSD(std::vector< PSDContinuous > &psd, unsigned n)
Definition: PSDContinuous.cc:134
double radius
Definition: PSDContinuous.h:202
static double getD100(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:162
static double getD50(const std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.h:154
static void print(std::vector< PSDContinuous > &psd)
Definition: PSDContinuous.cc:32
friend std::istream & operator>>(std::istream &is, PSDContinuous &psd)
Reads from input stream.
Definition: PSDContinuous.h:197
static std::vector< PSDContinuous > createPSDFromRadiiAndProbabilities(const std::vector< double > &radius, const std::vector< double > &probability)
Definition: PSDContinuous.cc:68