MercuryDPM  0.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ChuteWithHopperAndInset_copy_of_ChuteWithHopper.h
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 #include "Chute.h"
27 #include "Statistics.h"
28 
35 class ChuteWithHopperAndInset : public Chute {
36 protected:
38  double HopperLength;
40  double HopperHeight;
42  double HopperAngle;
48  double shift;
53 private:
55  double lift;
56 
58  unsigned int hopper_dim;
59 
61  bool align_base;
62 
64  double fill_percent;
65 
66 
67 public:
68 
70  ChuteWithHopperAndInset(Chute& other) : MD(other), Chute(other) {constructor();}
71  ChuteWithHopperAndInset(HGRID_3D& other) : MD(other), Chute(other) {constructor();}
72  ChuteWithHopperAndInset(HGRID_base& other) : MD(other), Chute(other) {constructor();}
73  ChuteWithHopperAndInset(MD& other) : MD(other), Chute(other) {constructor();}
74 
77 
79  void constructor()
80  {
81  lowerFillHeight=0.5;
82  lift=0.0;
83  set_Hopper(0.01, 0.01, 60.0, 0.08);
84  shift = 0.0;
85  hopper_dim=1;
86  align_base=true;
87 
88  fill_percent=50.0;
89  centerHopper=false;
90 
91  }
92 
93  void set_HopperFillPercentage(double new_fill){fill_percent=new_fill;}
94 
96  {
98  //std::cout << shift << " " << get_xmax() << " " << get_N() << std::endl;
99  add_hopper();
100  }
101 
103  void add_hopper() {
104  //hopper walls
105  int n = get_NWall();
106  set_NWall(n+2);
107 
108  //to create the finite hopper walls, we take vector between two wall points in xz-plane, then rotate clockwise and make unit length
109  // A\ /A
110  // \ / A,B,C denote three points on the left and right hopper walls which are used to construct the hopper
111  // \ / shift denotes the space by which the chute has to be shifted to the right such that the hopper is in the domain
112  // B| |B
113  // | |
114  // | |C
115  // C|
116 
117  Vec3D A, B, C, temp, normal;
118  double s = sin(get_ChuteAngle());
119  double c = cos(get_ChuteAngle());
121  HopperHeight = HopperLowestPoint + 1.1 * 0.5*(HopperLength+HopperExitLength) / tan(HopperAngle);
122  double HopperCornerHeight = HopperHeight - 0.5*(HopperLength-HopperExitLength) / tan(HopperAngle);
123  if (HopperCornerHeight<=0.0) { HopperHeight += -HopperCornerHeight + P0.Radius; HopperCornerHeight = P0.Radius; }
124 
125  //first we create the left hopper wall
126 
127  //coordinates of A,B,C in (vertical parallel to flow,vertical normal to flow, horizontal) direction
129  B = Vec3D(0.0, 0.0, HopperCornerHeight);
130  C = Vec3D(0.0, 0.0, 0.0);
131 
132 
133 
134  //now rotate the coordinates of A,B,C to be in (x,y,z) direction
135  A = Vec3D(c*A.X-s*A.Z, 0.0, s*A.X+c*A.Z);
136  B = Vec3D(c*B.X-s*B.Z, 0.0, s*B.X+c*B.Z);
137  C = Vec3D(c*C.X-s*C.Z, 0.0, s*C.X+c*C.Z);
138  // the position of A determines shift and zmax
140  if (centerHopper) set_shift(-A.X+40);
141  else set_shift(-A.X);
142  set_zmax(A.Z);
143  A.X +=shift;
144  B.X +=shift;
145  C.X +=shift;
146 
147  //This lifts the hopper a distance above the chute
148  A.Z+=lift;
149  B.Z+=lift;
150  C.Z+=lift;
151 
152  //create a finite wall from B to A and from C to B
153  temp = B-A;
154  normal = Vec3D(temp.Z,0.0,-temp.X) / sqrt(temp.GetLength2());
155  Walls[n].add_finite_wall(normal, Dot(normal,A));
156  temp = C-B;
157  normal = Vec3D(temp.Z,0.0,-temp.X) / sqrt(temp.GetLength2());
158  Walls[n].add_finite_wall(normal, Dot(normal,B));
159  temp = A-C;
160  normal = Vec3D(temp.Z,0.0,-temp.X)/sqrt(temp.GetLength2());
161  Walls[n].add_finite_wall(normal,Dot(normal,C));
162 
163 
164 
165  //next, do the same for the right wall
167  B = Vec3D(0.5*(HopperLength+HopperExitLength)-0.5*(HopperLength-HopperExitLength), 0.0, HopperCornerHeight);
168  C = Vec3D(0.5*(HopperLength+HopperExitLength)-0.5*(HopperLength-HopperExitLength), 0.0, HopperLowestPoint);
169 
170 
171 
172 
173  //This rotates the right points
174  A = Vec3D(c*A.X-s*A.Z+shift, 0.0, s*A.X+c*A.Z);
175  B = Vec3D(c*B.X-s*B.Z+shift, 0.0, s*B.X+c*B.Z);
176  C = Vec3D(c*C.X-s*C.Z+shift, 0.0, s*C.X+c*C.Z);
177 
178  //This lifts the hopper a distance above the chute
179  A.Z+=lift;
180  B.Z+=lift;
181  C.Z+=lift;
182 
183  temp = A-B;
184  normal = Vec3D(temp.Z,0.0,-temp.X) / sqrt(temp.GetLength2());
185  Walls[n+1].add_finite_wall(normal, Dot(normal,A));
186  temp = B-C;
187  normal = Vec3D(temp.Z,0.0,-temp.X) / sqrt(temp.GetLength2());
188  Walls[n+1].add_finite_wall(normal, Dot(normal,B));
189  temp = C-A;
190  normal = Vec3D(temp.Z,0.0,-temp.X) / sqrt(temp.GetLength2());
191  Walls[n+1].add_finite_wall(normal, Dot(normal,C));
192 
193  set_zmax(A.Z);
194 
195  if (hopper_dim == 2)
196  {
197 
198  set_NWall(n+4);
199 
200 
201  //coordinates of A,B,C in (vertical parallel to flow,vertical normal to flow, horizontal) direction
202  A = Vec3D(0.0, (get_ymax()-get_ymin()-HopperLength)/2.0, HopperHeight);
203  B = Vec3D(0.0, (get_ymax()-get_ymin()-HopperExitLength)/2.0, HopperCornerHeight);
204  C = Vec3D(0.0, (get_ymax()-get_ymin()-HopperExitLength)/2.0, 0.0);
205 
206 
207 
208  //now rotate the coordinates of A,B,C to be in (x,y,z) direction
209  A = Vec3D(c*A.X-s*A.Z, A.Y, s*A.X+c*A.Z);
210  B = Vec3D(c*B.X-s*B.Z, B.Y, s*B.X+c*B.Z);
211  C = Vec3D(c*C.X-s*C.Z, C.Y, s*C.X+c*C.Z);
212  // the position of A determines shift and zmax
213  A.X +=shift;
214  B.X +=shift;
215  C.X +=shift;
216 
217  //This lifts the hopper a distance above the chute
218  A.Z+=lift;
219  B.Z+=lift;
220  C.Z+=lift;
221 
222 
223 
224  //create a finite wall from B to A and from C to B
225  temp = B-A;
226  normal=Cross(Vec3D(-c,0,-s),temp)/sqrt(temp.GetLength2());
227  //normal = Vec3D(0.0,temp.Z,-temp.Y) / sqrt(temp.GetLength2());
228  Walls[n+2].add_finite_wall(normal, Dot(normal,A));
229  temp = C-B;
230  //normal = Vec3D(0.0,temp.Z,-temp.Y) / sqrt(temp.GetLength2());
231  normal=Cross(Vec3D(-c,0,-s),temp)/sqrt(temp.GetLength2());
232  Walls[n+2].add_finite_wall(normal, Dot(normal,B));
233  temp = A-C;
234  //normal = Vec3D(0.0,temp.Z,-temp.Y)/sqrt(temp.GetLength2());
235  normal=Cross(Vec3D(-c,0,-s),temp)/sqrt(temp.GetLength2());
236  Walls[n+2].add_finite_wall(normal,Dot(normal,C));
237 
238 
239  //Now for the right y-wall
240  A = Vec3D(0.0, (get_ymax()-get_ymin()+HopperLength)/2.0,HopperHeight);
241  B = Vec3D(0.0, (get_ymax()-get_ymin()+HopperExitLength)/2.0,HopperCornerHeight);
242  C = Vec3D(0.0, (get_ymax()-get_ymin()+HopperExitLength)/2.0,0.0);
243 
244  //now rotate the coordinates of A,B,C to be in (x,y,z) direction
245  A = Vec3D(c*A.X-s*A.Z, A.Y, s*A.X+c*A.Z);
246  B = Vec3D(c*B.X-s*B.Z, B.Y, s*B.X+c*B.Z);
247  C = Vec3D(c*C.X-s*C.Z, C.Y, s*C.X+c*C.Z);
248  // the position of A determines shift and zmax
249  A.X +=shift;
250  B.X +=shift;
251  C.X +=shift;
252 
253  //This lifts the hopper a distance above the chute
254  A.Z+=lift;
255  B.Z+=lift;
256  C.Z+=lift;
257 
258  //create a finite wall from B to A and from C to B
259  temp = A-B;
260  normal=Cross(Vec3D(-c,0,-s),temp)/sqrt(temp.GetLength2());
261  //normal = Vec3D(0.0,-temp.Z,temp.Y) / sqrt(temp.GetLength2());
262  Walls[n+3].add_finite_wall(normal, Dot(normal,A));
263  temp = B-C;
264  //normal = Vec3D(0.0,-temp.Z,temp.Y) / sqrt(temp.GetLength2());
265  normal=Cross(Vec3D(-c,0,-s),temp)/sqrt(temp.GetLength2());
266  Walls[n+3].add_finite_wall(normal, Dot(normal,B));
267  temp = C-A;
268  //normal = Vec3D(0.0,-temp.Z,temp.Y)/sqrt(temp.GetLength2());
269  normal=Cross(Vec3D(-c,0,-s),temp)/sqrt(temp.GetLength2());
270  Walls[n+3].add_finite_wall(normal,Dot(normal,C));
271 
272 
273 
274 
275 
276 
277 
278 
279  }
280 
281 
282 
283 
284 
285 
286 
287  //now shift the fixed particles at the bottom so that they begin where the chute begins
288  for (vector<CParticle>::iterator it= this->Particles.begin(); it!=this->Particles.end(); ++it) {
289  it->Position.X +=shift;
290  #ifdef USE_SIMPLE_VERLET_INTEGRATION
291  it->PrevPosition.X +=shift;
292  #endif
293  }
294  }
295 
296 
302  virtual void create_inflow_particle()
303  {
304 
305 
306  //use this formula to obtain bidispersed particles
307  //P0.Radius = random(0.0,1.0)<0.1?MinInflowParticleRadius:MaxInflowParticleRadius;
308 
309  //the following formula yields polydispersed particle radii:
312 
313  //Define a orthogonal coordinate system this is usful in the hopper, see diagram in html documentation for details.
314  static double s = sin(get_ChuteAngle());
315  static double c = cos(get_ChuteAngle());
316  static double Ht = tan(HopperAngle);
317  static double Hc = cos(HopperAngle);
318  static Vec3D AB = Vec3D(c,0.0,s);
319  static Vec3D AC = Vec3D(-s,0.0,c);
320  static Vec3D AD = Vec3D(0.0,1.0,0.0);
321 
322  //Point A is located in the centre of the hopper.
323  static Vec3D A = Vec3D
324  (
325  centerHopper?40:0.0,
326  (get_ymax()-get_ymin())/2.0,
328  )
329  + AB*0.5*HopperLength
330  + AC*(-0.5*HopperLength/Ht);
331 
332  double gamma = random((100.0-fill_percent)/100.0,1.0);
333 
334 
335  // double gamma = random(lowerFillHeight,1.0);
336 
337  double delta;
338 
339  if (hopper_dim==1)
340  {
341 
342 
343  //For the one dimensional delta is a random distance between the two walls the -minus 2 particle radii is to stop
345  //delta = random(ymin+P0.Radius,ymax-P0.Radius);
346  delta = random(-0.5,0.5)*(get_ymax()-get_ymin()-2.0*P0.Radius);
347  }
348  else
349  {
350 
351  delta= (random(-1.0,1.0)*(0.5*gamma*HopperLength -P0.Radius/Hc));
352  }
353  P0.Position = A
354  + AC * (gamma*0.5*HopperLength/Ht)
355  + AB * (random(-1.0,1.0)*(0.5*gamma*HopperLength - P0.Radius/Hc))
356  + AD*delta;
357 
358 
359  P0.Position.Z +=lift;
360 
361  //P0.Position.Y = random(ymin+P0.Radius, ymax-P0.Radius);
362  //P0.Position.Y=delta;
363 
364 
365 
366  }
367 
368  void set_Hopper(double ExitLength, double ExitHeight, double Angle, double Length){
369  if (ExitLength>=0.0) {HopperExitLength = ExitLength;} else std::cerr << "WARNING : Hopper exit length must be greater than or equal to zero" << std::endl;
370  if (ExitHeight>=0.0) {HopperExitHeight = ExitHeight;} else std::cerr << "WARNING : Hopper exit height must be greater than or equal to zero" << std::endl;
371  if (Angle>0.0&&Angle<90.0) {HopperAngle = Angle*pi/180.0;} else std::cerr << "WARNING : Hopper angle must in (0,90)" << std::endl;
372  if (Length>ExitLength) {HopperLength = Length;} else std::cerr << "WARNING : Hopper length must be greater than exit length" << std::endl;
373  }
374 
377  double height = HopperHeight+(get_xmax()-shift)*sin(ChuteAngle);
378  return sqrt(2.0*9.8*height);
379  }
380 
382  double get_ChuteLength(){return get_xmax()-shift;}
384  void set_ChuteLength(double new_){if (new_>=0.0) {set_xmax(new_+shift); set_xmin(0.0);} else std::cerr << "WARNING : Chute length unchanged, value must be greater than or equal to zero" << std::endl;}
385 
386  void set_centerHopper(bool new_){centerHopper=new_; }
387 
388  void set_lowerFillHeight(double new_){lowerFillHeight=new_; }
389 
390  void set_shift(double new_){if (new_>=0.0) {set_xmax(get_xmax()+new_-shift); shift = new_;} else std::cerr << "WARNING : Shift length unchanged, value must be greater than or equal to zero" << std::endl;}
391 
393  virtual void read(std::istream& is) {
394  Chute::read(is);
396  >> HopperAngle >> HopperHeight >> shift;
397  }
398 
400  virtual void write(std::ostream& os) {
401  Chute::write(os);
402  os << HopperExitLength << " " << HopperExitHeight << " " << HopperLength
403  << " " << HopperAngle << " " << HopperHeight << " " << shift << " " << std::endl;
404  }
405 
406  virtual void print(std::ostream& os) {
407  Chute::print(os);
408  os
409  << ", HopperExitLength:" << HopperExitLength
410  << ", HopperExitHeight:" << HopperExitHeight
411  << ", HopperLength:" << HopperLength
412  << ", HopperAngle:" << HopperAngle
413  << ", HopperHeight:" << HopperHeight
414  << std::endl;
415  }
416 
418  void lift_hopper(double distance){lift=distance;}
419  double get_lift_hopper(){return lift;}
420 
421  void set_hopper_dim(double new_hopper_dim){hopper_dim=new_hopper_dim;}
422 
423  void set_align_base(bool new_align){align_base=new_align;}
424 
425  int readNextArgument(unsigned int& i, unsigned int argc, char *argv[]) {
426  if (!strcmp(argv[i],"-hopperLength")) {
427  HopperLength=(atof(argv[i+1]));
428  } else if (!strcmp(argv[i],"-hopperHeight")) {
429  HopperHeight=(atof(argv[i+1]));
430  } else if (!strcmp(argv[i],"-hopperAngle")) {
431  HopperAngle=(atof(argv[i+1]));
432  } else if (!strcmp(argv[i],"-hopperExitLength")) {
433  HopperExitLength=(atof(argv[i+1]));
434  } else if (!strcmp(argv[i],"-hopperExitHeight")) {
435  HopperExitHeight=(atof(argv[i+1]));
436  } else if (!strcmp(argv[i],"-lowerFillHeight")) {
437  lowerFillHeight=(atof(argv[i+1]));
438  } else if (!strcmp(argv[i],"-centerHopper")) {
439  centerHopper=(atoi(argv[i+1]));
440  } else if (!strcmp(argv[i],"-alignBase")) {
441  align_base=(atoi(argv[i+1]));
442  } else if (!strcmp(argv[i],"-shift")) {
443  shift=(atof(argv[i+1]));
444  } else if (!strcmp(argv[i],"-lift")) {
445  lift=(atof(argv[i+1]));
446  } else return Chute::readNextArgument(i, argc, argv); //if argv[i] is not found, check the commands in Chute
447  return true; //returns true if argv[i] is found
448  }
449 
450 };
unsigned int hopper_dim
This is the dimension of the hopper, my default it is one dimensional and hence does not have side wa...
virtual void write(std::ostream &os)
This function writes all chute data.
Mdouble MinInflowParticleRadius
Definition: Chute.h:254
This is the base class for both HGRID_2D and HGRID_3D.
Definition: HGRID_base.h:43
void set_zmax(Mdouble new_zmax)
Sets ymax and walls, assuming the standard definition of walls as in the default constructor.
Definition: MD.h:334
Mdouble X
Definition: Vector.h:44
double HopperExitLength
Dimension of the hopper exit in vertical direction.
void compute_particle_mass(std::vector< CSpecies > &Species)
Compute Particle mass function, which required a reference to the Species vector. It copmuters the Pa...
int readNextArgument(unsigned int &i, unsigned int argc, char *argv[])
Definition: Chute.cc:414
Matrix3D Cross(const Vec3D &A, const Matrix3D &B)
Definition: Matrix.h:198
virtual void create_inflow_particle()
This creates an inflow particle in the top 50% of the hopper i.e.
void set_xmin(Mdouble new_xmin)
Sets xmin and walls, assuming the standard definition of walls as in the default constructor.
Definition: MD.h:318
double lift
This is the vertical distance the chute is lifted above the plane.
std::vector< CSpecies > Species
These are the particle parameters like dissipation etc.
Definition: MD.h:655
int readNextArgument(unsigned int &i, unsigned int argc, char *argv[])
double HopperHeight
Dimension of the hopper in horizontal direction.
void add_hopper()
This create the hopper on top of the chute, see diagram in class description for details of the point...
RNG random
Definition: MD.h:515
Mdouble get_ymax()
Gets ymax.
Definition: MD.h:311
friend Mdouble GetLength2(const Vec3D &A)
Definition: Vector.h:183
ChuteWithHopperAndInset(Chute &other)
This is a copy constructor for Chute problems.
bool align_base
This is the flag, which sets if the chute bottom is aligned with the hopper, by default it is...
void constructor()
The actually constructor.
Chute adds three new effects to the HGrid: the gravity direction can be set using the ChuteAngle vari...
Definition: Chute.h:34
virtual void setup_particles_initial_conditions()
initialize particle position, velocity, radius
double shift
The x position where the Chute starts (defined as the beginning of the hopper)
ChuteWithHopperAndInset has a hopper as inflow.
This adds on the hierarchical grid code for 3D problems.
Definition: HGRID_3D.h:35
void lift_hopper(double distance)
This lifts the hopper above the plane of the chute.
Mdouble get_ymin()
Gets ymin.
Definition: MD.h:309
double HopperLength
Dimension of the hopper in vertical direction.
const Mdouble pi
Definition: ExtendedMath.h:54
double lowerFillHeight
Relative height (in [0,1)) above which teh hopper is replenished with new particles.
void setup_particles_initial_conditions()
initialize particle position, velocity, radius
Definition: Chute.cc:229
bool centerHopper
If theis flag is set, the hopper will be constructed in the xy-center of the domain, and not next to the xmin-domain boundary; by default off.
void set_ChuteLength(double new_)
Allows chute length to be changed.
double HopperAngle
Angle between the two pieces of the hopper walls.
TangentialSpringParticle P0
Definition: Chute.h:262
double fill_percent
This is which percentage of the hopper is used for creating new partices;.
ChuteWithHopperAndInset()
This is the default constructor.
void print(std::ostream &os, bool print_all=false)
This function std::couts all chute data.
Definition: Chute.cc:88
virtual void read(std::istream &is)
This function reads all chute data.
A class that defines and solves a MD problem.
Definition: MD.h:70
double get_MaximumVelocityInducedByGravity()
Allows chute length to be accessed.
Mdouble gamma(Mdouble gamma_in)
This is the gamma function returns the true value for the half integer value.
Definition: ExtendedMath.cc:37
Mdouble ChuteAngle
Definition: Chute.h:252
Mdouble MaxInflowParticleRadius
Definition: Chute.h:255
void read(std::istream &is)
This function reads all chute data.
Definition: Chute.cc:46
Mdouble get_xmax()
Get xmax.
Definition: MD.h:307
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:40
double get_ChuteLength()
Allows chute length to be accessed.
Mdouble HopperLowestPoint
The z coordinate of the right C point (when the left C point is in the origin)
double HopperExitHeight
Dimension of the hopper exit in vertical direction.
Mdouble Z
Definition: Vector.h:44
virtual void write(std::ostream &os)
This function writes all chute data.
Definition: Chute.cc:70
void set_Hopper(double ExitLength, double ExitHeight, double Angle, double Length)
Mdouble get_ChuteAngle()
Gets chute angle (in radians)
Definition: Chute.h:108
void set_xmax(Mdouble new_xmax)
Sets xmax and walls, assuming the standard definition of walls as in the default constructor.
Definition: MD.h:328