AxisymmetricHopper.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 #include <string.h>
6 
7 #include "Chute.h"
9 #include "Math/ExtendedMath.h"
11 using namespace std;
12 
14 class AxisymmetricHopper : public Chute
15 {
16 public:
17 
19  {
20  setXMin(0);
21  setYMin(0);
22  setZMin(0);
23  setXMax(20);
24  setYMax(20);
25  setZMax(10);
26  setTimeMax(0);
27  FunnelMinRadius = -1; //radius at funnel outlet
28  FunnelMaxRadius = -1; //radius at upper funnel surface
29  FunnelHeight = -1; //height/thickness of funnel
30  FunnelInflowHeight = -1; //height/thickness of region where particles are included
31  num_created = 0;
32  max_failed = 100;
33  FunnelPointOnAxis.setZero();
34  }
35 
36  void setupInitialConditions() override
37  {
38  //do not write first time step, as there are zero particles in it
39  setLastSavedTimeStep(1);
40 
41  //Rudi's chute: rmin=H=12.5, rmax=34, dndt=95 500/s= 747 /sqrt(d/g)
42  //Rudi's large chute: rmin=14, H=25, rmax=55.5, dndt=215 000/s = 1682 /sqrt(d/g)
43  //tmax=3s=380 sqrt(d/g)
44  //real chute: dndt=700 000/s = 5477 /sqrt(d/g)
45 
46  if (Vec3D::getLength(FunnelPointOnAxis) == 0.0)
47  FunnelPointOnAxis = Vec3D(0.5 * (getXMax() + getXMin()), 0.5 * (getYMax() + getYMin()), 0);
48  Mdouble PossibleRadius = 0.5 * (getXMax() - getXMin());
49  if (FunnelMaxRadius == -1)
50  FunnelMaxRadius = PossibleRadius;
51  if (FunnelMinRadius == -1)
52  FunnelMinRadius = FunnelMaxRadius / 3.;
53  if (FunnelHeight == -1)
54  FunnelHeight = (FunnelMaxRadius - FunnelMinRadius) / mathsFunc::sin(45. * constants::pi / 180.); //60 deg (2./cos(60.*constants::pi/180.))
55  setZMax(getZMax() + FunnelHeight);
56  if (FunnelInflowHeight == -1)
57  FunnelInflowHeight = min(FunnelHeight / 4., 25. * getInflowParticleRadius());
58 
59  //create particle properties
60  Mdouble tc = .1;
61 
62  auto species = speciesHandler.copyAndAddObject(LinearViscoelasticFrictionSpecies());
63  species->setDensity(6.0 / constants::pi);
64  //species->setCollisionTimeAndRestitutionCoefficient(tc, 2.0 / 3.0, 0.5 * species->getMassFromRadius(0.5 * (getMinInflowParticleRadius() + getMaxInflowParticleRadius()))));
65  species->setCollisionTimeAndRestitutionCoefficient(tc, 2.0 / 3.0, species->getMassFromRadius(0.5 * (getMinInflowParticleRadius() + getMaxInflowParticleRadius())));
66  setTimeStep(tc / 10.);
67  setSaveCount(helpers::getSaveCountFromNumberOfSavesAndTimeMaxAndTimeStep(50, getTimeMax(), getTimeStep()));
68  species->setSlidingStiffness(2. / 7. * species->getStiffness());
69  species->setSlidingDissipation(2. / 7. * species->getDissipation());
70  species->setSlidingFrictionCoefficient(0.4);
71  species->setRollingStiffness(2. / 7. * species->getStiffness());
72  species->setRollingDissipation(2. / 7. * species->getDissipation());
73  species->setRollingFrictionCoefficient(0.1);
74 
75  //set walls
77  w0.setSpecies(speciesHandler.getObject(0));
78  //for a prism wall, define points ABC (or more points)
79  //as the corners of the prism base (ordered in clockwise
80  //direction) and D as the 'periodic direction' of the prism
81  //(upwards: Vec3D::Cross(A-B,D) has to point into the wall)
82  Vec3D A(FunnelMinRadius, 0, getZMax() - FunnelHeight);
83  Vec3D B(FunnelMaxRadius, 0, getZMax());
84  Vec3D C(FunnelMaxRadius, 0, getZMax() - FunnelHeight);
85  Vec3D D(0, 1, 0); //Periodic direction of the prism
86  w0.addObject(Vec3D::cross(A - B, D), A);
87  w0.addObject(Vec3D::cross(B - C, D), B);
88  w0.addObject(Vec3D::cross(C - A, D), C);
89  w0.setPosition(FunnelPointOnAxis);
90  w0.setAxis(Vec3D(0, 0, 1));
91  wallHandler.copyAndAddObject(w0);
92 
93  write(std::cout, false);
94  }
95 
96  void actionsBeforeTimeStep() override
97  {
98  add_particles();
99  cleanChute();
100  }
101 
103  {
104  //the following formula yields polydispersed particle radii:
105  P0.setRadius(random.getRandomNumber(getMinInflowParticleRadius(), getMaxInflowParticleRadius()));
106  //P0.computeMass(speciesHandler);
107  Mdouble R = random.getRandomNumber(0, FunnelMaxRadius - P0.getRadius());
108  Mdouble A = random.getRandomNumber(0, 2 * constants::pi);
109  double xhat = R * mathsFunc::cos(A);
110  double zhat = random.getRandomNumber(getZMax() - FunnelInflowHeight + P0.getRadius(), getZMax() - P0.getRadius());
111  double c = mathsFunc::cos(getChuteAngle());
112  double s = mathsFunc::sin(getChuteAngle());
113  P0.setPosition(FunnelPointOnAxis + Vec3D(xhat * c - zhat * s, R * mathsFunc::sin(A), zhat * c + xhat * s));
114  P0.setVelocity(Vec3D(0, 0, 0));
115  P0.setSpecies(speciesHandler.getObject(0));
116  }
117 
119  {
120  unsigned int failed = 0;
121 
122  //try max_failed times to find new insertable particle
123  while (failed <= max_failed)
124  {
125  create_inflow_particle();
126  if (checkParticleForInteraction (P0))
127  {
128  particleHandler.copyAndAddObject(P0);
129  failed = 0;
130  num_created++;
131  }
132  else
133  {
134  failed++;
135  }
136  };
137  }
138 
139  virtual void cleanChute()
140  {
141  //clean outflow every 100 time steps
142  static int count = 0, maxcount = 100;
143  if (count > maxcount)
144  {
145  count = 0;
146  // delete all outflowing particles
147  for (unsigned int i = 0; i < particleHandler.getNumberOfObjects();)
148  {
149  if (particleHandler.getObject(i)->getPosition().Z < getZMin())
150  {
151  particleHandler.removeObject(i);
152  }
153  else
154  i++;
155  }
156  }
157  else
158  count++;
159  }
160 
161  bool readNextArgument(int& i, int argc, char *argv[]) override
162  {
163  if (!strcmp(argv[i], "-inflowHeight"))
164  {
165  setInflowHeight(atof(argv[i + 1]));
166  setZMax(atof(argv[i + 1]));
167  }
168  else if (!strcmp(argv[i], "-FunnelMinRadius"))
169  {
170  set_FunnelMinRadius(atof(argv[i + 1]));
171  }
172  else if (!strcmp(argv[i], "-FunnelMaxRadius"))
173  {
174  set_FunnelMaxRadius(atof(argv[i + 1]));
175  }
176  else if (!strcmp(argv[i], "-FunnelHeight"))
177  {
178  set_FunnelHeight(atof(argv[i + 1]));
179  }
180  else if (!strcmp(argv[i], "-FunnelInflowHeight"))
181  {
182  set_FunnelInflowHeight(atof(argv[i + 1]));
183  }
184  else
185  return Chute::readNextArgument(i, argc, argv); //if argv[i] is not found, check the commands in Mercury3D
186  return true; //returns true if argv[i] is found
187  }
188 
190  {
191  FunnelMinRadius = new_;
192  }
193 
195  {
196  FunnelMaxRadius = new_;
197  }
198 
200  {
201  FunnelHeight = new_;
202  }
203 
205  {
206  if (FunnelHeight < new_)
207  {
208  logger(ERROR, "FunnelInflowHeight=% < FunnelHeight=%", new_);
209  }
210  FunnelInflowHeight = new_;
211  }
212 
213 
214 protected:
221  unsigned int max_failed;
222  unsigned int num_created;
223 };
int i
Definition: BiCGSTAB_step_by_step.cpp:9
dominoes D
Definition: Domino.cpp:55
Species< LinearViscoelasticNormalSpecies, FrictionSpecies > LinearViscoelasticFrictionSpecies
Definition: LinearViscoelasticFrictionSpecies.h:12
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ ERROR
@ R
Definition: StatisticsVector.h:21
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
Matrix< Scalar, Dynamic, Dynamic > C
Definition: bench_gemm.cpp:49
Matrix< SCALARB, Dynamic, Dynamic, opt_B > B
Definition: bench_gemm.cpp:48
Definition: AxisymmetricHopper.h:15
void set_FunnelInflowHeight(Mdouble new_)
Definition: AxisymmetricHopper.h:204
void add_particles()
Definition: AxisymmetricHopper.h:118
void set_FunnelMinRadius(Mdouble new_)
Definition: AxisymmetricHopper.h:189
Mdouble FunnelMinRadius
Definition: AxisymmetricHopper.h:216
void set_FunnelHeight(Mdouble new_)
Definition: AxisymmetricHopper.h:199
void set_FunnelMaxRadius(Mdouble new_)
Definition: AxisymmetricHopper.h:194
Vec3D FunnelPointOnAxis
Definition: AxisymmetricHopper.h:215
bool readNextArgument(int &i, int argc, char *argv[]) override
Interprets the i^th command-line argument.
Definition: AxisymmetricHopper.h:161
void create_inflow_particle()
Definition: AxisymmetricHopper.h:102
Mdouble FunnelHeight
Definition: AxisymmetricHopper.h:218
Mdouble FunnelMaxRadius
Definition: AxisymmetricHopper.h:217
SphericalParticle P0
Definition: AxisymmetricHopper.h:220
unsigned int num_created
Definition: AxisymmetricHopper.h:222
Mdouble FunnelInflowHeight
Definition: AxisymmetricHopper.h:219
virtual void cleanChute()
Definition: AxisymmetricHopper.h:139
void setupInitialConditions() override
This function allows to set the initial conditions for our problem to be solved, by default particle ...
Definition: AxisymmetricHopper.h:36
AxisymmetricHopper()
Definition: AxisymmetricHopper.h:18
unsigned int max_failed
Definition: AxisymmetricHopper.h:221
void actionsBeforeTimeStep() override
A virtual function which allows to define operations to be executed before the new time step.
Definition: AxisymmetricHopper.h:96
Use AxisymmetricIntersectionOfWalls to Screw Screw::read Screw::read Screw::read define axisymmetric ...
Definition: AxisymmetricIntersectionOfWalls.h:105
void setAxis(Vec3D a)
Definition: AxisymmetricIntersectionOfWalls.cc:149
virtual void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
Definition: BaseInteractable.h:218
Creates chutes with different bottoms. Inherits from Mercury3D (-> MercuryBase -> DPMBase).
Definition: Chute.h:44
bool readNextArgument(int &i, int argc, char *argv[]) override
This method can be used for reading object properties from a string.
Definition: Chute.cc:534
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
void addObject(Vec3D normal, Vec3D point)
Adds a wall to the set of infinite walls, given a normal vector pointing into the wall (i....
Definition: IntersectionOfWalls.cc:117
void setSpecies(const ParticleSpecies *species)
sets species of subwalls as well
Definition: IntersectionOfWalls.cc:51
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:16
Definition: Kernel/Math/Vector.h:30
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:143
Mdouble getLength() const
Calculates the length of this Vec3D: .
Definition: Vector.cc:339
Definition: matrices.h:74
#define min(a, b)
Definition: datatypes.h:22
RealScalar s
Definition: level1_cplx_impl.h:130
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::enable_if_t< dt !=data_source::global_mem, void > write(PacketType &packet_data, DataScalar ptr)
write, a template function used for storing the data to local memory. This function is used to guaran...
Definition: TensorContractionSycl.h:221
double P0
Definition: two_dim.cc:101
int c
Definition: calibrate.py:100
const Mdouble pi
Definition: ExtendedMath.h:23
unsigned int getSaveCountFromNumberOfSavesAndTimeMaxAndTimeStep(unsigned int numberOfSaves, Mdouble timeMax, Mdouble timeStep)
Returns the correct saveCount if the total number of saves, the final time and the time step is known...
Definition: FormulaHelpers.cc:75
Mdouble cos(Mdouble x)
Definition: ExtendedMath.cc:43
Mdouble sin(Mdouble x)
Definition: ExtendedMath.cc:23