MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ChuteBottom.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, 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 
27 #include "ChuteBottom.h"
31 #include "Walls/InfiniteWall.h"
32 #include <Logger.h>
33 
38 {
39  constructor();
40 }
41 
50  : DPMBase(other), Chute(other)
51 {
52  constructor();
53 }
54 
63  : DPMBase(other), Chute(other)
64 {
65  constructor();
66 }
67 
76  : DPMBase(other), Chute(other)
77 {
78  constructor();
79 }
80 
89  : DPMBase(other), Chute(other)
90 {
91  constructor();
92 }
93 
100  : DPMBase(other), Chute(other),
101  thickness_(other.thickness_), isBottomPeriodic_(other.isBottomPeriodic_)
102 {
103 
104 }
105 
110 {
111  setName("roughbottom");
112  fStatFile.setFileType(FileType::NO_FILE); //set to 0 for no data creation
115  setThickness(2.4);
116  setIsBottomPeriodic(true);
117 }
118 
133 {
134  // set up mini-simulation with particle inflow on the left end and horizontal chute
135  // set all parameters that should be different from the original chute
136  setChuteAngle(0.0);
138  //~ setInflowHeight(45.*getInflowParticleRadius());
139  // note: Changing the Inflow height was an attempt to make the bottom density homogeneous, but it did not have the desired effect
142 
143  auto species = dynamic_cast<LinearViscoelasticNormalSpecies*>(speciesHandler.getObject(0));
144  if (species != nullptr)
145  {
148  //this number is chosen to be consistent with the old implementation (with contained a bug and was replaced); originally, a factor of 10.0 (and a restitution of 0.2) was chosen.
149  const Mdouble collisionTime = 13.2863 * species->getCollisionTime(mass);
150  species->setCollisionTimeAndRestitutionCoefficient(collisionTime, 0.343008, mass);
151  setTimeStep(0.02 * 9.41823 * collisionTime);
152  logger(INFO, "Time step: %", getTimeStep());
153  logger(INFO, "Species: %", *species);
154  }
155  else
156  {
158  logger(WARN, "[ChuteBottom::makeRoughBottom()] species type does not allow setting the parameters.");
159  }
160 
161  auto species2 = dynamic_cast<SlidingFrictionSpecies*>(speciesHandler.getObject(0));
162  if (species2 != nullptr)
163  species2->setSlidingFrictionCoefficient(0);
164 
165  // set the simulation to run for 2000 time steps
166  setTimeMax(getTimeStep() * 2000);
167  //set_number_of_saves(2);
168  setSaveCount(100);
169 
170  // run the simulation
171  solve();
172 
173  //Find the Z-position of the highest particle in the system
174  Mdouble height = 0;
175  for (BaseParticle* b : particleHandler)
176  {
177  height = std::max(height, b->getPosition().Z);
178  }
179 
180  // Next, all particles are removed from the system, except those with a Z-position s.t.:
181  // hmax = height - maxInflowParticleRadius_;
182  // hmax - thickness_ * maxInflowParticleRadius_ < Z-position < hmax
183  // note that hmax = height - rMax
184  logger(INFO, "[ChuteBottom::makeRoughBottom()] Thickness: %", thickness_);
190  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end();)
191  {
192  if ((*it)->getPosition().Z < height - (1.0 + thickness_) * getMaxInflowParticleRadius() ||
193  (*it)->getPosition().Z > height - getMaxInflowParticleRadius())
194  {
195  //delete particles outside the given range
196  particleHandler.removeObject((*it)->getIndex());
197  }
198  else
199  {
200  // Move remaining particles to the floor
201  (*it)->move(Vec3D(0.0, 0.0, getMaxInflowParticleRadius() - height));
202 
203  // fix them to the bottom
204  (*it)->fixParticle();
205  it++;
206  }
207  }
208 
209  //copy the rough bottom over
210  chute.particleHandler.setStorageCapacity(particleHandler.getNumberOfObjects());
211  logger(INFO, "[ChuteBottom::makeRoughBottom()] Chute bottom finished, consisting of % particles",
212  particleHandler.getNumberOfObjects());
214 
222  for (BaseParticle* p : chute.particleHandler)
223  {
224  p->setSpecies(chute.speciesHandler.getObject(0));
225  }
226 
227 }
228 
234 {
235 
236  particleHandler.setStorageCapacity(static_cast<unsigned int>(std::min(3.0 * getXMax() * getYMax() * getZMax() / mathsFunc::cubic(2.0 * getInflowParticleRadius()), 1e6)));
237 
238  createBottom();
239 
245  wallHandler.clear();
247  if (isBottomPeriodic_)
248  {
249  InfiniteWall w0;
251  w0.set(Vec3D(0.0, 0.0, -1.0), Vec3D(0, 0, getZMin() - getInflowParticleRadius()));
253  PeriodicBoundary b0;
254  b0.set(Vec3D(1.0, 0.0, 0.0), getXMin(), getXMax());
256  b0.set(Vec3D(0.0, 1.0, 0.0), getYMin(), getYMax());
258  }
259  else
260  {
261  InfiniteWall w0;
263  w0.set(Vec3D(0.0, 0.0, -1.0), Vec3D(0, 0, getZMin() - getInflowParticleRadius()));
265  w0.set(Vec3D(-1.0, 0.0, 0.0), Vec3D(getXMin(), 0, 0));
267  w0.set(Vec3D(1.0, 0.0, 0.0), Vec3D(getXMax(), 0, 0));
269  w0.set(Vec3D(0.0, -1.0, 0.0), Vec3D(0, getYMin(), 0));
271  w0.set(Vec3D(0.0, 1.0, 0.0), Vec3D(0, getYMax(), 0));
273  }
274 
275  // add particles
282  unsigned int failed = 0;
283  const unsigned int max_failed = 500;
284 
285  BaseParticle inflowParticle_;
286  inflowParticle_.setSpecies(speciesHandler.getObject(0));
287  inflowParticle_.setHandler(&particleHandler);
288  inflowParticle_.setOrientation(Vec3D(0.0, 0.0, 0.0));
289  inflowParticle_.setAngularVelocity(Vec3D(0.0, 0.0, 0.0));
290 
291  // try max_failed times to find new insertable particle
292  // every time an insertion succeeds the counter failed is set to 0 again.
293  while (failed <= max_failed)
294  {
295  inflowParticle_.setRadius(getFixedParticleRadius());
296  //inflowParticle_.computeMass();
297 
298  // The position components are first stored in a Vec3D, because if you pass
299  // them directly into setPosition the compiler is allowed to change the order
300  // in which the numbers are generated
301  Vec3D position;
302  position.X = random.getRandomNumber(inflowParticle_.getRadius(), getXMax() - inflowParticle_.getRadius());
303  position.Y = random.getRandomNumber(inflowParticle_.getRadius(), getYMax() - inflowParticle_.getRadius());
304  position.Z = random.getRandomNumber(2 * inflowParticle_.getRadius(), getZMax() - inflowParticle_.getRadius());
305  inflowParticle_.setPosition(position);
306  inflowParticle_.setVelocity(Vec3D(0.0, 0.0, 0.0));
307 
308  //if the volume we want to insert the particle is still free, insert the particle
309  if (checkParticleForInteraction(inflowParticle_))
310  {
311  particleHandler.copyAndAddObject(inflowParticle_);
312  failed = 0;
313  }
314  else
315  {
316  failed++;
317  }
318  }
319  //set_Nmax(particleHandler.getNumberOfObjects());
320  logger(INFO, "[ChuteBottom::setupInitialConditions()] Number of particles created: %",
322 
323  //fix hgrid (there is still an issue when particles are polydispersed)
324  //assume 1-2 levels are optimal (which is the case for mono and bidispersed) and set the cell size to min and max
325  // !this is not optimal for polydispersed
326  Mdouble minCell = 2. * std::min(getFixedParticleRadius(), getMinInflowParticleRadius());
327  Mdouble maxCell = 2. * std::max(getFixedParticleRadius(), getMaxInflowParticleRadius());
328  if ((minCell == maxCell) | (minCell == 0.))
330  else
332  //set_HGRID_cell_to_cell_ratio (1.0000000001*maxCell/minCell);
333  //optimize number of buckets
334  //setHGridNumberOfBucketsToPower(particleHandler.getNumberOfObjects() * 1.5);
335  //end: fix hgrid
336 
337  //~ write(std::cout,false);
338 }
339 
345 {
346 }
347 
354 {
355  return thickness_;
356 }
357 
364 {
365  if (new_ > 0.0)
366  thickness_ = new_;
367  else
368  {
369  logger(ERROR, "[ChuteBottom::setThickness()] thickness % negative.", new_);
370  }
371 }
372 
378 {
379  return isBottomPeriodic_;
380 }
381 
386 void ChuteBottom::setIsBottomPeriodic(bool isBottomPeriodic)
387 {
388  isBottomPeriodic_ = isBottomPeriodic;
389 }
void setInflowHeight(Mdouble inflowHeight)
Sets maximum inflow height (Z-direction)
Definition: Chute.cc:861
void set(Vec3D normal, Mdouble distanceLeft, Mdouble distanceRight)
Defines a periodic wall.
void solve()
The work horse of the code.
Definition: DPMBase.cc:2188
bool checkParticleForInteraction(const BaseParticle &P) override
Checks if given BaseParticle has an interaction with a BaseWall or other BaseParticle.
Definition: MercuryBase.cc:609
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:65
Mdouble X
the vector components
Definition: Vector.h:52
ChuteBottom()
This is the default constructor. All it does is set sensible defaults.
Definition: ChuteBottom.cc:37
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
void setTimeMax(Mdouble newTMax)
Allows the upper time limit to be changed.
Definition: DPMBase.cc:199
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void setOrientation(const Vec3D &orientation)
Sets the orientation of this BaseInteractable.
Mdouble getZMax() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMax() returns ZMax...
Definition: DPMBase.cc:319
Mdouble getXMin() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMin() returns XMin...
Definition: DPMBase.cc:279
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:501
File restartFile
An instance of class File to handle in- and output into a .restart file.
Definition: Files.h:219
Used by Chute::createBottom to create an unordered particle layer.
Definition: ChuteBottom.h:39
void setHandler(ParticleHandler *handler)
Sets the pointer to the particle's ParticleHandler.
Mdouble getYMin() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMin() returns YMin...
Definition: DPMBase.cc:295
double Mdouble
void setChuteAngle(Mdouble chuteAngle)
Sets gravity vector according to chute angle (in degrees)
Definition: Chute.cc:672
void setSpecies(const ParticleSpecies *species)
void setRadius(const Mdouble radius)
Sets the particle's radius_ (and adjusts the mass_ accordingly, based on the particle's species) ...
void setRoughBottomType(RoughBottomType roughBottomType)
Sets the type of rough bottom of the chute.
Definition: Chute.cc:618
Defines a pair of periodic walls. Inherits from BaseBoundary.
Mdouble getXMax() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMax() returns XMax...
Definition: DPMBase.cc:287
Mdouble getInflowParticleRadius() const
Returns the average radius of inflow particles.
Definition: Chute.cc:833
void constructor()
This is the actual constructor METHOD; it is called by all constructors above (except the default cop...
Definition: ChuteBottom.cc:109
Mdouble thickness_
Thickness of the multilayer chute rough bottom. See also documentation of ChuteBottom::makeRoughBotto...
Definition: ChuteBottom.h:123
Creates chutes with different bottoms. Inherits from Mercury3D (-> MercuryBase -> DPMBase)...
Definition: Chute.h:62
This is the base class for both Mercury2D and Mercury3D. Note the actually abstract grid is defined i...
Definition: MercuryBase.h:127
Mdouble getMaxInflowParticleRadius() const
Returns the maximum radius of inflow particles.
Definition: Chute.cc:851
void makeRoughBottom(Chute &chute)
Makes a multilayered rough bottom with thickness thickness_.
Definition: ChuteBottom.cc:132
void setupInitialConditions()
Sets up initial conditions before running a chute simulation.
Definition: ChuteBottom.cc:233
file will not be created/read
LinearViscoelasticNormalSpecies contains the parameters used to describe a linear elastic-dissipative...
Mdouble getMassFromRadius(const Mdouble radius) const
void setIsBottomPeriodic(bool isBottomPeriodic)
Sets whether the bottom should be periodic in Y.
Definition: ChuteBottom.cc:386
void setName(const std::string &name)
Allows to set the name of all the files (ene, data, fstat, restart, stat)
Definition: Files.cc:150
BoundaryHandler boundaryHandler
An object of the class BoundaryHandler which concerns insertion and deletion of particles into or fro...
Definition: DPMBase.h:1011
Mdouble getFixedParticleRadius() const
Returns the particle radius of the fixed particles which constitute the (rough) chute bottom...
Definition: Chute.cc:603
Mdouble getThickness() const
Returns the thickness of the multilayer rough bottom.
Definition: ChuteBottom.cc:353
This adds on the hierarchical grid code for 3D problems.
Definition: Mercury3D.h:35
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created...
Definition: DPMBase.h:1001
all data will be written into/ read from a single file called name_
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:451
File fStatFile
An instance of class File to handle in- and output into a .fstat file.
Definition: Files.h:209
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:295
T cubic(T val)
calculates the cube of a number
Definition: ExtendedMath.h:99
void setSaveCount(unsigned int saveCount)
Sets File::saveCount_ for all files (ene, data, fstat, restart, stat)
Definition: Files.cc:139
File dataFile
An instance of class File to handle in- and output into a .data file.
Definition: Files.h:204
void setSlidingFrictionCoefficient(Mdouble new_mu)
Allows the (dynamic) Coulomb friction coefficient to be changed; also sets mu_s by default...
Mdouble getRadius() const
Returns the particle's radius_.
void setHGridMaxLevels(unsigned int HGridMaxLevels)
Sets the maximum number of levels of the HGrid in this MercuryBase.
Definition: MercuryBase.cc:500
unsigned int getNumberOfObjects() const
Gets the number of Object in this BaseHandler.
Definition: BaseHandler.h:487
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. elastic, linear visco-elastic... et cetera...
Definition: DPMBase.h:991
void hGridActionsBeforeTimeLoop() override
This sets up the broad phase information, has to be done at this stage because it requires the partic...
Definition: MercuryBase.cc:95
Mdouble getYMax() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMax() returns XMax...
Definition: DPMBase.cc:303
Mdouble Y
Definition: Vector.h:52
SlidingFrictionSpecies contains the parameters used to describe sliding friction. ...
void setFileType(FileType fileType)
Sets the type of file needed to write into or read from. File::fileType_.
Definition: File.cc:210
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1006
void setFixedParticleRadius(Mdouble fixedParticleRadius)
Sets the particle radius of the fixed particles which constitute the (rough) chute bottom...
Definition: Chute.cc:585
RNG random
This is a random generator, often used for setting up the initial conditions etc...
Definition: DPMBase.h:996
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
virtual void createBottom()
Creates the chute bottom, which can be either flat or one of three flavours of rough.
Definition: Chute.cc:316
Mdouble getMinInflowParticleRadius() const
returns the minimum radius of inflow particles
Definition: Chute.cc:842
void set(Vec3D normal, Vec3D point)
Defines a standard wall, given an outward normal vector s.t. normal*x=normal*point for all x of the w...
Definition: InfiniteWall.cc:79
Mdouble getZMin() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMin() returns ZMin...
Definition: DPMBase.cc:311
void setTimeStep(Mdouble newDt)
Allows the time step dt to be changed.
Definition: DPMBase.cc:451
This is a class defining walls.
Definition: InfiniteWall.h:47
void setThickness(Mdouble thickness)
Sets the thickness of the multilayer rough bottom.
Definition: ChuteBottom.cc:363
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
Mdouble getTimeStep() const
Allows the time step dt to be accessed.
Definition: DPMBase.cc:465
Mdouble Z
Definition: Vector.h:52
void setAngularVelocity(const Vec3D &angularVelocity)
set the angular velocity of the BaseInteractble.
bool isBottomPeriodic_
TRUE if the bottom is periodic in Y.
Definition: ChuteBottom.h:128
Mdouble getRandomNumber(Mdouble min, Mdouble max)
This is a random generating routine can be used for initial positions.
Definition: RNG.cc:101
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
Definition: BaseHandler.h:392
void actionsBeforeTimeStep()
Performs all necessary actions before the start of a time step (none in this case) ...
Definition: ChuteBottom.cc:344
void setSpecies(const ParticleSpecies *species)
Define the species of this wall.
Definition: BaseWall.cc:113
bool getIsBottomPeriodic() const
Returns TRUE if the bottom is periodic in Y.
Definition: ChuteBottom.cc:377