obsolete_codes/SilbertPeriodic.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 #include "scr/Chute.h"
27 //~ #include "scr/Time.h"
28 using namespace std;
29 
30 class SilbertPeriodic : public Chute
31 {
32 public:
33 
35  // Problem parameters
36  setName("silbert");
37 
38  //time stepping
39  setTimeStep(1e-4);
40  setTimeMax(2000);
41 
42  //output parameters
43  setSaveCount(50e4);
44 
45  //particle radii
46  setInflowParticleRadius(.5);
47  setFixedParticleRadius(.5);//getInflowParticleRadius());
48  setRoughBottomType(MULTILAYER);
49 
50  //particle properties
51  setDensity(6/constants::pi);
52  setStiffness(2e5);
53  setSlidingStiffness(2.0/7.0*getStiffness());
54  setDissipation(25.0);
55  //setSlidingDissipation(2.0/7.0*getDissipation());
56  setSlidingDissipation(getDissipation());
57  setSlidingFrictionCoefficient(0.5);
58 
59  //chute properties
60  setChuteAngle(24.0, 1.0);
61  setChuteLength(20);
62  setChuteWidth(10);
63  set_H(20);
64 
65  }
66 
67  void fix_hgrid() {
68  //assume 1-2 levels are optimal (which is the case for mono and bidispersed) and set the cell size to min and max
69  // !this is not optimal for polydispersed
70  Mdouble minCell = 2.*min(getFixedParticleRadius(),getMinInflowParticleRadius());
71  Mdouble maxCell = 2.*max(getFixedParticleRadius(),getMaxInflowParticleRadius());
72  if ((minCell==maxCell)|(minCell==0.)) set_HGRID_max_levels(1);
73  else set_HGRID_max_levels(2);
74  set_HGRID_cell_to_cell_ratio (1.0000001*maxCell/minCell);
75  }
76 
78  if (speciesHandler.getNumberOfObjects()>1) return speciesHandler.getMixedObject(1,0)->getSlidingFrictionCoefficient();
79  else return getSlidingFrictionCoefficient();
80  }
81 
83  createBaseSpecies();
84  speciesHandler.getMixedObject(1, 0)->setSlidingFrictionCoefficient(new_);
85  }
86 
87  virtual void createBaseSpecies() {
88  //only create once
89  static bool created=false;
90  if (!created) {
91  speciesHandler.copyAndAddObject(speciesHandler.getObject(0));
92  created = true;
93  for (unsigned int i=0; i<particleHandler.getNumberOfObjects(); i++) {
94  if (particleHandler.getObject(i)->isFixed()) particleHandler.getObject(i)->setSpecies(speciesHandler.getObject(1));
95  }
96  }
97  }
98 
99  void set_study() {
100  stringstream name;
101  name << "H" << getInflowHeight()
102  << "A" << getChuteAngleDegrees()
103  << "L" << round(100.*getFixedParticleRadius()*2.)/100.
104  << "M" << getSlidingFrictionCoefficient()
105  << "B" << getSlidingFrictionCoefficientBottom();
106  setName(name.str().c_str());
107  set_data_filename();
108  }
109 
110  void set_study(int study_num) {
111  //S=0-5: lambda = 0, 3./6., 4./6., 5./6., 1, 2
112  //S=6-8: mu = 0, 1, inf
113  //S=9-13: mub = 0,1,inf,1/4,1/8
114  //S=14-15: mu = 1/4, 1/8
115  //S=16-19: lambda = 1./6., 2./6., 1.5, 4
116  //S=21-25: mub=1/16,1/32,1/64,1/128,1/1024
117  //S=26-28: lambda=1/2, mub=1/16,1/128,1/1024
118  //S=29-32: lambda=0, mub=1/16,1/128,1/1024,0
119 
120  if (study_num < 6) {
121  // set mu_all = 0.5, vary lambda
122  Mdouble Lambdas[] = {0, 3./6., 4./6., 5./6., 1, 2};
123  setFixedParticleRadius(Lambdas[study_num]/2.);
124  setSlidingFrictionCoefficient(0.5);
125  } else if (study_num < 9) { //Case 6,7,8
126  // set lambda = 1, vary mu_all
127  Mdouble MuAll[] = {0, 1., 1e20};
128  setSlidingFrictionCoefficient(MuAll[study_num-6]);
129  setFixedParticleRadius(0.5);
130  } else if (study_num < 12) { //Case 9,10,11
131  // set lambda = 1, mu_all = 0.5, vary mu_bottom
132  Mdouble MuBottom[] = {0, 1., 1e20};
133  setSlidingFrictionCoefficient(0.5);
134  setSlidingFrictionCoefficientBottom(MuBottom[study_num-9]);
135  setFixedParticleRadius(0.5);
136  } else if (study_num < 14) { //Case 12,13
137  // set lambda = 1, mu_all = 0.5, vary mu_bottom
138  Mdouble MuBottom[] = {0.25, 0.125};
139  setSlidingFrictionCoefficient(0.5);
140  setSlidingFrictionCoefficientBottom(MuBottom[study_num-12]);
141  setFixedParticleRadius(0.5);
142  } else if (study_num < 16) { //Case 14,15
143  // set lambda = 1, vary mu_all
144  Mdouble MuAll[] = {0.25, 0.125};
145  setSlidingFrictionCoefficient(MuAll[study_num-14]);
146  setFixedParticleRadius(0.5);
147  } else if (study_num < 21) { //Case 16,17,18,19,20
148  // set mu_all = 0.5, vary lambda
149  Mdouble Lambdas[] = {1./6., 2./6., 1.5, 4, 1./12};
150  setFixedParticleRadius(Lambdas[study_num-16]/2.);
151  setSlidingFrictionCoefficient(0.5);
152  } else if (study_num < 26) { //Case 21 22 23 24 25
153  // set lambda = 1, mu_all = 0.5, vary mu_bottom
154  Mdouble MuBottom[] = {1./16.,1./32.,1./64.,1./128.,1./1024.};
155  setSlidingFrictionCoefficient(0.5);
156  setSlidingFrictionCoefficientBottom(MuBottom[study_num-21]);
157  setFixedParticleRadius(0.5);
158  } else if (study_num < 29) { //Case 26 27 28
159  // set lambda = 1/2, mu_all = 0.5, vary mu_bottom
160  Mdouble MuBottom[] = {1./16.,1./128.,1./1024.};
161  setSlidingFrictionCoefficient(0.5);
162  setSlidingFrictionCoefficientBottom(MuBottom[study_num-26]);
163  setFixedParticleRadius(0.25);
164  } else if (study_num < 33) { //Case 29 30 31 32
165  // set lambda = 0, mu_all = 0.5, vary mu_bottom
166  Mdouble MuBottom[] = {1./16.,1./128.,1./1024.,0};
167  setSlidingFrictionCoefficient(0.5);
168  setSlidingFrictionCoefficientBottom(MuBottom[study_num-29]);
169  setFixedParticleRadius(0);
170  } else if (study_num < 37) { //Case 33-36
171  cout << "S" << study_num << endl;
172  // set lambda = 1, mu_b = 0.5, vary mu
173  Mdouble Mu[] = {1e20,1,1./64,0};
174  setSlidingFrictionCoefficient(Mu[study_num-33]);
175  setSlidingFrictionCoefficientBottom(0.5);
176  setFixedParticleRadius(1);
177  } else {
178  //If study_num is complete quit
179  cout << "Study is complete " << endl;
180  exit(0);
181  }
182  //Note make sure h and a is defined
183  set_study();
184  }
185 
186  void set_study(vector<int> study_num) {
187  Mdouble Heights[] = {10, 20, 30, 40};
188  Mdouble Angles[] = {20, 22, 24, 26, 28, 30, 40, 50, 60};
189  setInflowHeight(Heights[study_num[1]-1]);
190  setChuteAngle(Angles[study_num[2]-1]);
191  set_study(study_num[0]);
192  }
193 
194  //Do not add or remove particles
195  void actionsBeforeTimeStep() override { };
196 
197  //Set up periodic walls, rough bottom, add flow particles
198  void setupInitialConditions() override
199  {
200  fix_hgrid();
201  particleHandler.set_StorageCapacity(particleHandler.getNumberOfObjects()+getChuteLength()*getChuteWidth()*getZMax());//why is this line needed?
202 
203  createBottom();
204  //~ write(std::cout,false);
205  //cout << "correct fixed" << endl;
206  if (Species.size()>1) {
207  for (unsigned int i=0; i<particleHandler.getNumberOfObjects(); i++)
208  if (particleHandler.getObject(i)->isFixed())
209  particleHandler.getObject(i)->setSpecies(speciesHandler.getObject(1));
210  }
211 
212  set_NWall(1);
213  if (getFixedParticleRadius()) {
214  wallHandler.getObject(0)->set(Vec3D(0,0,-1), 3.4*MaxInflowParticleRadius);
215  } else {
216  wallHandler.getObject(0)->set(Vec3D(0,0,-1), 0.);
217  }
218 
219  set_NWallPeriodic(2);
220  WallsPeriodic[0].set(Vec3D( 1.0, 0.0, 0.0), getXMin(), getXMax());
221  WallsPeriodic[1].set(Vec3D( 0.0, 1.0, 0.0), getYMin(), getYMax());
222 
223  add_flow_particles();
224 
225  cout << endl << "Status before solve:" << endl;
226  cout
227  << "tc=" << getCollisionTime()
228  << ", eps=" << getRestitutionCoefficient()
229  << ", vmax=" << getMaximumVelocity()
230  << ", InflowHeight/zmax=" << getInflowHeight()/getZMax()
231  << endl << endl;
232  //~ timer.set(t,tmax);
233 
234  //optimize number of buckets
235  cout << "Nmax" << particleHandler.getStorageCapacity() << endl;
236  set_HGRID_num_buckets_to_power(particleHandler.getNumberOfObjects()*1.5);
237  }
238 
239  //add flow particles
241  {
242  set_HGRID_num_buckets_to_power(particleHandler.getStorageCapacity());
243  hGridActionsBeforeTimeLoop();
244  hGridActionsBeforeTimeStep();
245  unsigned int N=particleHandler.getNumberOfObjects()+getChuteLength()*getChuteWidth()*InflowHeight;
246  particleHandler.set_StorageCapacity(N);
247  Mdouble H = InflowHeight;
248  setZMax(1.2*InflowHeight);
249 
250  writeRestartFile();
251  //try to find new insertable particles
252  while (particleHandler.getNumberOfObjects()<N){
253  create_inflow_particle();
254  if (IsInsertable(P0)) {
255  num_created++;
256  } else InflowHeight += .0001* MaxInflowParticleRadius;
257  }
258  InflowHeight = H;
259  set_HGRID_num_buckets_to_power();
260  write(std::cout,false);
261  }
262 
263  //defines type of flow particles
265  {
266  P0.setRadius(random.get_RN(MinInflowParticleRadius,MaxInflowParticleRadius));
267  P0.computeMass(Species);
268 
269  P0.getPosition().X = random.get_RN(getXMin()+2.0*P0.getRadius(),getXMax());
270  P0.getPosition().Y = random.get_RN(getYMin()+2.0*P0.getRadius(),getYMax());
271  P0.getPosition().Z = random.get_RN(getZMin()+2.0*P0.getRadius(),getInflowHeight());
272  P0.setVelocity(Vec3D(0.0,0.0,0.0));
273  }
274 
275  //set approximate height of flow
276  void set_H(Mdouble new_) {InflowHeight=new_; setZMax(InflowHeight);}
277  Mdouble get_H() {return InflowHeight;}
278 
279  void printTime() {
280  cout << "t=" << setprecision(3) << left << setw(6) << getTime()
281  << ", tmax=" << setprecision(3) << left << setw(6) << getTimeMax()
282  << ", N=" << setprecision(3) << left << setw(6) << particleHandler.getNumberOfObjects()
283  //<< ", time left=" << setprecision(3) << left << setw(6) << timer.getTime2Finish(t)
284  //~ << ", finish by " << setprecision(3) << left << setw(6) << timer.getFinishTime(t)
285  << ". " << endl;
286  }
287 
288  int readNextArgument(unsigned int& i, unsigned int argc, char *argv[]) {
289  if (!strcmp(argv[i],"-muBottom")) {
290  setSlidingFrictionCoefficientBottom(atof(argv[i+1]));
291  cout << "muB=" << getSlidingFrictionCoefficientBottom() << endl;
292  } else return Chute::readNextArgument(i, argc, argv); //if argv[i] is not found, check the commands in Chute
293  return true; //returns true if argv[i] is found
294  }
295 };
@ MULTILAYER
Definition: Chute.h:53
Creates chutes with different bottoms. Inherits from Mercury3D (-> MercuryBase -> DPMBase).
Definition: Chute.h:65
bool readNextArgument(int &i, int argc, char *argv[]) override
This method can be used for reading object properties from a string.
Definition: Chute.cc:555
Definition: flowRuleDiego_HeightAngle.cpp:35
virtual void createBaseSpecies()
Definition: obsolete_codes/SilbertPeriodic.h:87
void set_study(vector< int > study_num)
Definition: obsolete_codes/SilbertPeriodic.h:186
void setSlidingFrictionCoefficientBottom(Mdouble new_)
Definition: obsolete_codes/SilbertPeriodic.h:82
void add_flow_particles()
Definition: obsolete_codes/SilbertPeriodic.h:240
void create_inflow_particle()
Definition: obsolete_codes/SilbertPeriodic.h:264
void set_study()
Definition: obsolete_codes/SilbertPeriodic.h:99
void set_H(Mdouble new_)
Definition: obsolete_codes/SilbertPeriodic.h:276
SilbertPeriodic()
Definition: obsolete_codes/SilbertPeriodic.h:34
void printTime()
Definition: obsolete_codes/SilbertPeriodic.h:279
void actionsBeforeTimeStep() override
A virtual function which allows to define operations to be executed before the new time step.
Definition: obsolete_codes/SilbertPeriodic.h:195
Mdouble get_H()
Definition: obsolete_codes/SilbertPeriodic.h:277
void fix_hgrid()
Definition: obsolete_codes/SilbertPeriodic.h:67
Mdouble getSlidingFrictionCoefficientBottom()
Definition: obsolete_codes/SilbertPeriodic.h:77
void set_study(int study_num)
Definition: obsolete_codes/SilbertPeriodic.h:110
void setupInitialConditions() override
This function allows to set the initial conditions for our problem to be solved, by default particle ...
Definition: obsolete_codes/SilbertPeriodic.h:198
int readNextArgument(unsigned int &i, unsigned int argc, char *argv[])
Definition: obsolete_codes/SilbertPeriodic.h:288
Contains material and contact force properties.
Definition: Species.h:35
Definition: Vector.h:51
const Mdouble pi
Definition: ExtendedMath.h:45
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
Mdouble round(Mdouble value, unsigned int precision)
rounds a floating point number with a given precision
Definition: MathHelpers.cc:28
MERCURYDPM_DEPRECATED Mdouble getMaximumVelocity(Mdouble k, Mdouble disp, Mdouble radius, Mdouble mass)
Calculates the maximum relative velocity allowed for a normal collision of two particles of radius r ...
Definition: FormulaHelpers.cc:68
std::string name
Definition: MercuryProb.h:48