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