Calibration.h
Go to the documentation of this file.
1 #ifndef MERCURYDPM_CALIBRATION_H
2 #define MERCURYDPM_CALIBRATION_H
3 
4 #include <vector>
5 #include <cstring>
8 #include "Math/PSD.h"
9 #include "Math/ExtendedMath.h"
10 #include "Mercury3D.h"
11 #include "DPMBase.h"
12 #include "cmath"
13 #include "Logger.h"
14 
15 using constants::pi;
16 using mathsFunc::cubic;
18 
19 class Calibration : public Mercury3D {
20 protected:
25  std::string param;
26 
27 public:
28  Calibration (int argc, char *argv[]) : Mercury3D() {
29  // string of parameter values added to file name
30  param = readFromCommandLine(argc,argv,"-param",std::string(""));
31  //define output file settings
32  setOutput(helpers::readFromCommandLine(argc,argv,"-output"));
33  // set psd
34  setPSD(argc, argv);
35  // set species
36  setSpecies(argc, argv);
37  }
38 
39  std::string getParam() {return param;}
40 
41  // sets default output file settings
42  void setOutput(bool output)
43  {
48  if (output) {
49  setSaveCount(1000);
52  //setParticlesWriteVTK(true);
53  }
54  //default xballs arguments
55  setXBallsAdditionalArguments("-v0 -solidf");
56  }
57 
58  // set psd from command line (-psd r1 p1 .. rn pn)
59  void setPSD(int argc, char *argv[]) {
60  for (unsigned i=0; i<argc-1; ++i) {
61  if (!strcmp(argv[i],"-psd")) {
62  std::vector<DistributionElements> psdVector;
64  // distribution type given
65  if (!strcmp(argv[i + 1], "logNormal"))
66  {
67  logger.assert_debug(argc > i + 5, "Error in logNormal");
68  // https://en.wikipedia.org/wiki/Log-normal_distribution
69  double meanX = std::atof(argv[i + 4]);
70  double stdX = std::atof(argv[i + 5]);
71  if (!strcmp(argv[i + 3], "radius"))
72  {
73  }
74  else if (!strcmp(argv[i + 3], "diameter"))
75  {
76  meanX /= 2;
77  stdX /= 2;
78  } else {
79  logger(ERROR,"setPSD: distribution type % not known", argv[i+3]);
80  }
81  double meanX2 = meanX*meanX;
82  double stdX2 = stdX*stdX;
83  double mean = log(meanX2/sqrt(meanX2+stdX2));
84  double std = sqrt(log(1+stdX2/meanX2));
85  double lnRMin = mean-2.5*std;
86  double lnRMax = mean+2.5*std;
87  unsigned n = 21;
88  psdVector.push_back({0.5*exp(lnRMin), 0});
89  if (std>0) {
90  for (int j = 1; j < n; ++j) {
91  double lnR = lnRMin + j / (double) n * (lnRMax - lnRMin);
92  value.internalVariable = exp(lnR);
93  value.probability = 0.5 * (1.0 + erf((lnR - mean) / (sqrt(2) * std)));
94  psdVector.push_back(value);
95  logger(INFO, "psd % %", value.internalVariable, value.probability);
96  }
97  }
98  psdVector.push_back({0.5*exp(lnRMax), 1});
99  if (!strcmp(argv[i+2],"number")) {
101  } else if (!strcmp(argv[i+2],"volume")) {
103  } else {
104  logger(ERROR,"setPSD: distribution type % not known", argv[i+2]);
105  }
106  return;
107  }
108  // distribution given
109  for (unsigned j=i+4; j<argc-2 && argv[j][0]!='-' && argv[j+1][0]!='-'; j+=2) {
110  if (!strcmp(argv[i+3],"radius")) {
111  value.internalVariable = std::atof(argv[j]);
112  } else if (!strcmp(argv[i+3],"diameter")) {
113  value.internalVariable = std::atof(argv[j]) / 2.;
114  } else {
115  logger(ERROR,"setPSD: distribution type % not known", argv[i+3]);
116  }
117  value.probability = std::atof(argv[j+1]);
118  psdVector.push_back(value);
119  }
120  if (!strcmp(argv[i+1],"cumulative")) {
121  if (!strcmp(argv[i+2],"number")) {
123  } else if (!strcmp(argv[i+2],"volume")) {
125  } else {
126  logger(ERROR,"setPSD: distribution type % not known", argv[i+1]);
127  }
128  } else if (!strcmp(argv[i+1],"probability")) {
129  if (!strcmp(argv[i+2],"number")) {
131  } else if (!strcmp(argv[i+2],"volume")) {
133  } else {
134  logger(ERROR,"setPSD: distribution type % not known", argv[i+1]);
135  }
136  } else {
137  logger(ERROR,"setPSD: distribution type % not known", argv[i+2]);
138  }
139  return;
140  }
141  }
142  //if the "-psd" is not found
143  logger(ERROR, "-psd argument not found");
144  }
145 
146  // set species from command line (-species, -density, etc)
147  void setSpecies(int argc, char *argv[]) {
148  std::string stringSpecies = readFromCommandLine(argc,argv,"-species",std::string(""));
149  if (stringSpecies == "LinearViscoelasticFrictionReversibleAdhesiveSpecies") {
150  //set species
152  //set density
153  species->setDensity(readFromCommandLine(argc,argv,"-density", constants::NaN));
154  double massMin = species->getMassFromRadius(psd.getMinRadius());
155  double massD50 = species->getMassFromRadius(psd.getVolumeDx(50));
156  //set constantRestitution
157  species->setConstantRestitution(readFromCommandLine(argc,argv,"-constantRestitution"));
158  //set collisionTime and restitutionCoefficient
159  double collisionTime = readFromCommandLine(argc,argv,"-collisionTime",0.0);
160  double restitutionCoefficient = readFromCommandLine(argc,argv,"-restitutionCoefficient",1.0);
161  species->setCollisionTimeAndRestitutionCoefficient(collisionTime, restitutionCoefficient, massMin);
162  // set slidingFriction, rollingFriction, torsionFriction
163  species->setSlidingFrictionCoefficient(readFromCommandLine(argc,argv,"-slidingFriction",0.0));
164  species->setSlidingStiffness(2. / 7. * species->getStiffness());
165  species->setSlidingDissipation(2. / 7. * species->getDissipation());
166  species->setRollingFrictionCoefficient(readFromCommandLine(argc,argv,"-rollingFriction",0.0));
167  species->setRollingStiffness(2. / 5. * species->getStiffness());
168  species->setRollingDissipation(2. / 5. * species->getDissipation());
169  species->setTorsionFrictionCoefficient(readFromCommandLine(argc,argv,"-torsionFriction",0.0));
170  species->setTorsionStiffness(2. / 5. * species->getStiffness());
171  species->setTorsionDissipation(2. / 5. * species->getDissipation());
172  // set adhesion
173  species->setAdhesionStiffness(species->getStiffness());
174  species->setAdhesionForceMax(9.8*massD50*readFromCommandLine(argc,argv,"-bondNumber",0.0));
175  // set timeStep
176  setTimeStep(0.05 * species->getCollisionTime(massMin));
177  // define side-wall species (no friction/cohesion)
178  auto frictionlessWallSpecies_ = speciesHandler.copyAndAddObject(species);
179  auto mixedSpecies = speciesHandler.getMixedObject(species, frictionlessWallSpecies_);
180  mixedSpecies->setRollingFrictionCoefficient(0.0);
181  mixedSpecies->setSlidingFrictionCoefficient(0.0);
182  mixedSpecies->setAdhesionForceMax(0.0);
183  // define drum-wall species (high friction/ no cohesion)
184  auto frictionalWallSpecies_ = speciesHandler.copyAndAddObject(species);
185  mixedSpecies = speciesHandler.getMixedObject(species, frictionalWallSpecies_);
186  mixedSpecies->setRollingFrictionCoefficient(std::max(1.0,species->getSlidingFrictionCoefficient())); //\todo TW infinity does not work (anymore?)
187  mixedSpecies->setSlidingFrictionCoefficient(std::max(1.0,species->getRollingFrictionCoefficient()));
188  mixedSpecies->setAdhesionForceMax(0.0);
189  // cast down
190  particleSpecies = species;
191  frictionalWallSpecies = frictionalWallSpecies_;
192  frictionlessWallSpecies = frictionlessWallSpecies_;
193  } else {
194  logger(ERROR,"Species % unknown", stringSpecies);
195  }
196  logger(INFO, "Species: %", *particleSpecies);
199  logger(INFO, "Time step %", getTimeStep());
200  }
201 
202  void writePSDToFile() {
203  // convert psd to volume cumulative diameter
204  std::ofstream out(getName()+".psd");
205  auto vpsd = psd;
206 // vpsd.convertCumulativeToProbabilityDensity();
207 // vpsd.convertProbabilityDensityNumberDistributionToProbabilityDensityVolumeDistribution();
208 // vpsd.convertProbabilityDensityToCumulative();
209  out << "Diameter volumeProbability\n";
210  for (auto p : vpsd.getParticleSizeDistribution())
211  out << p.internalVariable*2.0 << ' ' << p.probability << '\n';
212  // convert psd to volume cumulative diameter
213  std::ofstream out2(getName()+".psd2");
214  out2 << "Diameter volumeProbability\n";
215  for (auto p : particleHandler)
216  out2 << p->getRadius()*2.0 << '\n';
217  //get real distribution
218  helpers::writeToFile(getName()+"PSD.m",
219  "psd = importdata('" + getName() + ".psd',' ',1);\n"
220  "d=psd.data(:,1);\n"
221  "p=psd.data(:,2);\n"
222  "plot(d*1e6,p,'k.-',\"LineWidth\",2)\n"
223  "xlabel(\"diameter [um]\")\n"
224  "ylabel(\"number cumulative\")\n"
225  "axis padded\n"
226  "\n"
227  "hold on\n"
228  "psd2 = importdata('" + getName() + ".psd2',' ',1);\n"
229  "d=psd2.data(:,1);\n"
230  "histogram(d*1e6,'Normalization','cdf')\n"
231  "legend('exact','data')\n"
232  "set(legend,'Location','best')\n"
233  "hold off\n"
234  "\n"
235  "saveas(gcf,'" + getName() + ".psd.png')\n");
236  logger(INFO,"Run % to plot PSD",getName()+".m");
237  }
238 };
239 
240 #endif //MERCURYDPM_CALIBRATION_H
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
const unsigned NEVER
Definition: File.h:35
@ NO_FILE
file will not be created/read
@ ONE_FILE
all data will be written into/ read from a single file called name_
Species< LinearViscoelasticNormalSpecies, FrictionSpecies, ReversibleAdhesiveSpecies > LinearViscoelasticFrictionReversibleAdhesiveSpecies
Definition: LinearViscoelasticFrictionReversibleAdhesiveSpecies.h:35
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ INFO
@ ERROR
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject(const U &object)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:379
Definition: Calibration.h:19
Calibration(int argc, char *argv[])
Definition: Calibration.h:28
void writePSDToFile()
Definition: Calibration.h:202
ParticleSpecies * particleSpecies
Definition: Calibration.h:22
ParticleSpecies * frictionlessWallSpecies
Definition: Calibration.h:24
PSD psd
Definition: Calibration.h:21
void setPSD(int argc, char *argv[])
Definition: Calibration.h:59
void setSpecies(int argc, char *argv[])
Definition: Calibration.h:147
std::string param
Definition: Calibration.h:25
std::string getParam()
Definition: Calibration.h:39
ParticleSpecies * frictionalWallSpecies
Definition: Calibration.h:23
void setOutput(bool output)
Definition: Calibration.h:42
void setSaveCount(unsigned int saveCount)
Sets File::saveCount_ for all files (ene, data, fstat, restart, stat)
Definition: DPMBase.cc:408
File eneFile
An instance of class File to handle in- and output into a .ene file.
Definition: DPMBase.h:1488
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1427
Mdouble getTimeStep() const
Returns the simulation time step.
Definition: DPMBase.cc:1250
const std::string & getName() const
Returns the name of the file. Does not allow to change it though.
Definition: DPMBase.cc:399
File dataFile
An instance of class File to handle in- and output into a .data file.
Definition: DPMBase.h:1478
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1447
void setFileType(FileType fileType)
Sets File::fileType_ for all files (ene, data, fstat, restart, stat)
Definition: DPMBase.cc:459
File restartFile
An instance of class File to handle in- and output into a .restart file.
Definition: DPMBase.h:1493
void setXBallsAdditionalArguments(std::string newXBArgs)
Set the additional arguments for xballs.
Definition: DPMBase.cc:1347
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1437
void setTimeStep(Mdouble newDt)
Sets a new value for the simulation time step.
Definition: DPMBase.cc:1234
class of DistributionElements which stores internalVariables and probabilities of a distribution....
Definition: DistributionElements.h:34
Mdouble internalVariable
Definition: DistributionElements.h:36
Mdouble probability
Definition: DistributionElements.h:37
void setFileType(FileType fileType)
Sets the type of file needed to write into or read from. File::fileType_.
Definition: File.cc:215
This adds on the hierarchical grid code for 3D problems.
Definition: Mercury3D.h:37
Contains a vector with radii and probabilities of a user defined particle size distribution (PSD)
Definition: PSD.h:65
Mdouble getMinRadius() const
Get smallest radius of the PSD.
Definition: PSD.cc:886
Mdouble getVolumeDx(Mdouble x) const
Calculate a certain diameter (e.g. D10, D50, D90, etc.) from a percentile x of the volume based PSD.
Definition: PSD.cc:777
@ PROBABILITYDENSITY_VOLUME_DISTRIBUTION
@ CUMULATIVE_VOLUME_DISTRIBUTION
@ PROBABILITYDENSITY_NUMBER_DISTRIBUTION
@ CUMULATIVE_NUMBER_DISTRIBUTION
MERCURYDPM_DEPRECATED void setPSDFromVector(std::vector< DistributionElements > psd, TYPE PSDType)
Deprecated version of reading in PSDs from a vector.
Definition: PSD.cc:396
Definition: ParticleSpecies.h:37
std::enable_if<!std::is_pointer< typename U::MixedSpeciesType >::value, typename U::MixedSpeciesType * >::type getMixedObject(const U *S, const U *T)
Definition: SpeciesHandler.h:74
void setWriteVTK(FileType)
Sets whether walls are written into a VTK file.
Definition: WallHandler.cc:467
const Mdouble NaN
Definition: GeneralDefine.h:43
const Mdouble pi
Definition: ExtendedMath.h:45
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
bool readFromCommandLine(int argc, char *argv[], std::string varName)
Returns true if command line arguments contain varName, false else.
Definition: CommandLineHelpers.cc:103
bool writeToFile(std::string filename, std::string filecontent)
Writes a string to a file.
Definition: FileIOHelpers.cc:58
Mdouble log(Mdouble Power)
Definition: ExtendedMath.cc:104
Mdouble exp(Mdouble Exponent)
Definition: ExtendedMath.cc:84
T cubic(const T val)
calculates the cube of a number
Definition: ExtendedMath.h:115