VerticalMixer.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 "Material.h"
27 #include <Walls/InfiniteWall.h>
30 
33 struct VerticalMixer : public Material {
34 
35  VerticalMixer (int argc, char *argv[]) : Material (argc, argv) {}
36 
42  //two options for plotting walls
43  bool prettyWalls_ = false;
44  bool haveOuterWalls = true;
45 
46  void setupInitialConditions() override {
47  //set general properties
49  setMin(-getMax());
50  setGravity(Vec3D(0, 0, -9.8));
51 
52  //set timestep
53  //setTimeStep(species.getCollisionTime(mass)/15);
54  //14*collisiontime for nice flow for
55  setSaveCount(200);
56 
57  //enforce writing wall output
59  //if (!prettyWalls_)
60  //setParticlesWriteVTK(true);
61 
62  Mdouble cornerLength = 8.0 * particleRadius_;
63  if (!prettyWalls_) {
64  //define Walls
67  outer.setAxis(Vec3D(1, 0, 0));
68  outer.addObject(Vec3D(1, 0, 0), Vec3D(drumRadius_, 0, 0));
70 
73  leftCorner.setAxis(Vec3D(1, 0, 0));
74  leftCorner.addObject(Vec3D(1, 0, -1), Vec3D(drumRadius_, 0, -0.5 * drumLength_ + cornerLength));
75  wallHandler.copyAndAddObject(leftCorner);
76 
78  rightCorner.setSpecies(frictionalWallSpecies);
79  rightCorner.setAxis(Vec3D(1, 0, 0));
80  rightCorner.addObject(Vec3D(1, 0, 1), Vec3D(drumRadius_, 0, 0.5 * drumLength_ - cornerLength));
81  wallHandler.copyAndAddObject(rightCorner);
82 
83  InfiniteWall leftEnd;
85  leftEnd.set(Vec3D(-1, 0, 0), Vec3D(-0.5 * drumLength_, 0, 0));
87 
88  InfiniteWall rightEnd;
90  rightEnd.set(Vec3D(1, 0, 0), Vec3D(0.5 * drumLength_, 0, 0));
91  wallHandler.copyAndAddObject(rightEnd);
92 
93  addBlades();
94 
95  } else {
96  Mdouble thickness = particleRadius_;
97  setMax(getMax()+Vec3D(1,1,1)*2*thickness);
98  setMin(getMin()-Vec3D(1,1,1)*2*thickness);
99 
100  if (haveOuterWalls) {
101  //define Walls
104  outer.setAxis(Vec3D(1, 0, 0));
105  outer.addObject(Vec3D(1, 0, 0), Vec3D(drumRadius_, 0, 0));
106  outer.addObject(Vec3D(-1, 0, 0), Vec3D(drumRadius_ + thickness, 0, 0));
107  outer.addObject(Vec3D(0, 0, 1), Vec3D(0, 0, -0.5 * drumLength_ + cornerLength));
108  outer.addObject(Vec3D(0, 0, -1), Vec3D(0, 0, 0.5 * drumLength_ - cornerLength));
110 
112  leftCorner.setSpecies(frictionalWallSpecies);
113  leftCorner.setAxis(Vec3D(1, 0, 0));
114  leftCorner.addObject(Vec3D(1, 0, -1), Vec3D(drumRadius_, 0, -0.5 * drumLength_ + cornerLength));
115  leftCorner.addObject(Vec3D(-1, 0, 1),
116  Vec3D(drumRadius_ + thickness, 0, -0.5 * drumLength_ + cornerLength));
117  leftCorner.addObject(Vec3D(0, 0, -1), Vec3D(0, 0, -0.5 * drumLength_ + cornerLength));
118  leftCorner.addObject(Vec3D(1, 0, 0), Vec3D(drumRadius_ - cornerLength, 0, 0));
119  wallHandler.copyAndAddObject(leftCorner);
120 
122  rightCorner.setSpecies(frictionalWallSpecies);
123  rightCorner.setAxis(Vec3D(1, 0, 0));
124  rightCorner.addObject(Vec3D(1, 0, 1), Vec3D(drumRadius_, 0, 0.5 * drumLength_ - cornerLength));
125  rightCorner.addObject(Vec3D(-1, 0, -1),
126  Vec3D(drumRadius_ + thickness, 0, 0.5 * drumLength_ - cornerLength));
127  rightCorner.addObject(Vec3D(0, 0, 1), Vec3D(0, 0, 0.5 * drumLength_ - cornerLength));
128  rightCorner.addObject(Vec3D(1, 0, 0), Vec3D(drumRadius_ - cornerLength, 0, 0));
129  wallHandler.copyAndAddObject(rightCorner);
130 
133  leftEnd.setAxis(Vec3D(1, 0, 0));
134  leftEnd.addObject(Vec3D(0, 0, 1), Vec3D(0, 0, -0.5 * drumLength_ - thickness));
135  leftEnd.addObject(Vec3D(0, 0, -1), Vec3D(0, 0, -0.5 * drumLength_));
136  leftEnd.addObject(Vec3D(-1, 0, 0), Vec3D(drumRadius_ - cornerLength, 0, 0));
137  wallHandler.copyAndAddObject(leftEnd);
138 
141  rightEnd.setAxis(Vec3D(1, 0, 0));
142  rightEnd.addObject(Vec3D(0, 0, -1), Vec3D(0, 0, 0.5 * drumLength_ + thickness));
143  rightEnd.addObject(Vec3D(0, 0, 1), Vec3D(0, 0, 0.5 * drumLength_));
144  rightEnd.addObject(Vec3D(-1, 0, 0), Vec3D(drumRadius_ - cornerLength, 0, 0));
145  wallHandler.copyAndAddObject(rightEnd);
146  }
147 
148  addPrettyBlades();
149  }
150 
151  for (BaseWall* w : wallHandler) {
152  w->setAngularVelocity(angularVelocity);
153  }
154 
158  CubeInsertionBoundary c; //delete is done in boundaryHandler
159  c.set(&p, 0, getMin(), getMax(), Vec3D(0, 0, 0), Vec3D(0, 0, 0));
160  //c.setPSD(PSD::getDistributionNormal(particleRadius_,0.025*particleRadius_,50));
161  c.setPSD(psd);
164  }
165 
166  void printTime() const override
167  {
168  logger(INFO,"t %\tN %\tE %\tC %",getTime(),particleHandler.getNumberOfObjects(),
170  }
171 
172  virtual void addBlades() {}
173 
174  virtual void addPrettyBlades() {}
175 };
176 
178 
179  VerticalMixerStraightBlades (int argc, char *argv[]) : VerticalMixer (argc, argv) {}
180 
183 
184  void addBlades() override {
185  IntersectionOfWalls blade;
190  Vec3D(0,-0.5*bladeWidth_,drumRadius_)});
192 
193  const Vec3D quarterTurn = {2,0,0};
194  blade.rotate(quarterTurn);
196  blade.rotate(quarterTurn);
198  blade.rotate(quarterTurn);
200  }
201 };
202 
204 
205  VerticalMixerAngledBlades (int argc, char *argv[]) : VerticalMixerStraightBlades (argc, argv) {}
206 
208 
209  void addBlades() override {
210  Mdouble s = sin(bladeAngle_);
211  Mdouble c = cos(bladeAngle_);
212 
213  IntersectionOfWalls blade;
218  Vec3D(-0.5*bladeWidth_*s,-0.5*bladeWidth_*c,drumRadius_)});
219  blade.setPosition(Vec3D(0.2*drumLength_,0,0));
221 
222  const Vec3D quarterTurn = {2,0,0};
223  blade.rotate(quarterTurn);
224  blade.setPosition(Vec3D(-0.2*drumLength_,0,0));
226  blade.rotate(quarterTurn);
227  blade.setPosition(Vec3D(0.2*drumLength_,0,0));
229  blade.rotate(quarterTurn);
230  blade.setPosition(Vec3D(-0.2*drumLength_,0,0));
232  }
233 
234  void addPrettyBlades() override {
235  Mdouble sb = sin(bladeAngle_);
236  Mdouble cb = cos(bladeAngle_);
237 
238  IntersectionOfWalls blade;
240  blade.createPrism({Vec3D(0.5*bladeWidth_*sb,0.5*bladeWidth_*cb,drumRadius_),
243  Vec3D(-0.5*bladeWidth_*sb,-0.5*bladeWidth_*cb,drumRadius_)});
244  //restrict to inside
245  Mdouble cornerLength = 8.0 * particleRadius_;
246  for (Mdouble angle = -0.2*constants::pi; angle<=0.2001*constants::pi; angle+=0.05*constants::pi) {
247  Mdouble s = sin(angle);
248  Mdouble c = cos(angle);
249  //outer.addObject(Vec3D(1, 0, 0), Vec3D(drumRadius_, 0, 0));
250  blade.addObject(Vec3D(0, s, -c), Vec3D(0, -s, c)*drumRadius_);
251  }
252  const Vec3D quarterTurn = {2,0,0};
253 
254  IntersectionOfWalls leftBlade = blade;
255  for (Mdouble angle = -0.2*constants::pi; angle<=0.2001*constants::pi; angle+=0.05*constants::pi) {
256  Mdouble s = sin(angle);
257  Mdouble c = cos(angle);
258  //leftCorner.addObject(Vec3D(1, 0, -1), Vec3D(drumRadius_, 0, -0.5 * drumLength_ + cornerLength));
259  leftBlade.addObject(Vec3D(1, s, -c), Vec3D(0.2*drumLength_-0.5 * drumLength_ + cornerLength, -s*drumRadius_, c*drumRadius_));
260  //blade.addObject(Vec3D(-1, s, -c), Vec3D(-0.2*drumLength_+0.5 * drumLength_ - cornerLength, -s*drumRadius_, c*drumRadius_));
261  }
262  leftBlade.setPosition(Vec3D(-0.2*drumLength_,0,0));
263  leftBlade.rotate(quarterTurn);
264  wallHandler.copyAndAddObject(leftBlade);
265  leftBlade.rotate(quarterTurn);
266  leftBlade.rotate(quarterTurn);
267  wallHandler.copyAndAddObject(leftBlade);
268 
269  IntersectionOfWalls rightBlade = blade;
270  for (Mdouble angle = -0.2*constants::pi; angle<=0.2001*constants::pi; angle+=0.05*constants::pi) {
271  Mdouble s = sin(angle);
272  Mdouble c = cos(angle);
273  //rightCorner.addObject(...);
274  rightBlade.addObject(Vec3D(-1, s, -c), Vec3D(-0.2*drumLength_+0.5 * drumLength_ - cornerLength, -s*drumRadius_, c*drumRadius_));
275  }
276  rightBlade.setPosition(Vec3D(0.2*drumLength_,0,0));
277  wallHandler.copyAndAddObject(rightBlade);
278  rightBlade.rotate(quarterTurn);
279  rightBlade.rotate(quarterTurn);
280  wallHandler.copyAndAddObject(rightBlade);
281  }
282 };
@ MULTIPLE_FILES
each time-step will be written into/read from separate files numbered consecutively: name_....
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ INFO
@ Z
Definition: StatisticsVector.h:42
Use AxisymmetricIntersectionOfWalls to Screw Screw::read Screw::read Screw::read define axisymmetric ...
Definition: AxisymmetricIntersectionOfWalls.h:126
void setAxis(Vec3D a)
Definition: AxisymmetricIntersectionOfWalls.cc:152
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:379
virtual void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
Definition: BaseInteractable.h:239
virtual void rotate(const Vec3D &angularVelocityDt)
Rotates this BaseInteractable.
Definition: BaseInteractable.cc:230
virtual Mdouble getVolume() const
Get Particle volume function, which required a reference to the Species vector. It returns the volume...
Definition: BaseParticle.cc:143
virtual void setRadius(Mdouble radius)
Sets the particle's radius_ (and adjusts the mass_ accordingly, based on the particle's species)
Definition: BaseParticle.cc:553
void setSpecies(const ParticleSpecies *species)
Definition: BaseParticle.cc:818
Basic class for walls.
Definition: BaseWall.h:49
void setSpecies(const ParticleSpecies *species)
Defines the species of the current wall.
Definition: BaseWall.cc:169
It's an insertion boundary which has cuboidal shape (yes, 'CuboidalInsertionBoundary' would have been...
Definition: CubeInsertionBoundary.h:42
void set(BaseParticle *particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax, Vec3D velMin={0, 0, 0}, Vec3D velMax={0, 0, 0})
Sets the properties of the InsertionBoundary for mutliple different particle types.
Definition: CubeInsertionBoundary.cc:107
void setSaveCount(unsigned int saveCount)
Sets File::saveCount_ for all files (ene, data, fstat, restart, stat)
Definition: DPMBase.cc:408
Mdouble getTime() const
Returns the current simulation time.
Definition: DPMBase.cc:808
Mdouble getKineticEnergy() const
Returns the global kinetic energy stored in the system.
Definition: DPMBase.cc:1544
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1447
Vec3D getMax() const
Definition: DPMBase.h:670
void setMin(const Vec3D &min)
Sets the minimum coordinates of the problem domain.
Definition: DPMBase.cc:1118
BoundaryHandler boundaryHandler
An object of the class BoundaryHandler which concerns insertion and deletion of particles into or fro...
Definition: DPMBase.h:1452
Vec3D getMin() const
Definition: DPMBase.h:664
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1437
Vec3D getCentreOfMass() const
JMFT: Return the centre of mass of the system, excluding fixed particles.
Definition: DPMBase.cc:1614
void setMax(const Vec3D &max)
Sets the maximum coordinates of the problem domain.
Definition: DPMBase.cc:1082
void setGravity(Vec3D newGravity)
Sets a new value for the gravitational acceleration.
Definition: DPMBase.cc:1383
Mdouble getElasticEnergy() const
Returns the global elastic energy within the system.
Definition: DPMBase.cc:1530
A infinite wall fills the half-space {point: (position_-point)*normal_<=0}.
Definition: InfiniteWall.h:48
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:118
void setPSD(const PSD psd)
Sets the range of particle radii that may be generated from a user defined PSD.
Definition: InsertionBoundary.cc:675
void setInitialVolume(Mdouble initialVolume)
Gets the Volume which should be inserted by the insertion routine.
Definition: InsertionBoundary.cc:643
A IntersectionOfWalls is convex polygon defined as an intersection of InfiniteWall's.
Definition: IntersectionOfWalls.h:59
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:138
void createPrism(std::vector< Vec3D > points, Vec3D prismAxis)
Creates an open prism which is a polygon between the points and extends infinitely in the PrismAxis d...
Definition: IntersectionOfWalls.cc:482
void createOpenPrism(std::vector< Vec3D > points, Vec3D prismAxis)
Creates an open prism which is a polygon between the points, except the first and last point,...
Definition: IntersectionOfWalls.cc:467
void setSpecies(const ParticleSpecies *species)
sets species of subwalls as well
Definition: IntersectionOfWalls.cc:72
Definition: Material.h:33
PSD psd
Definition: Material.h:35
ParticleSpecies * frictionalWallSpecies
Definition: Material.h:37
ParticleSpecies * particleSpecies
Definition: Material.h:36
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:777
unsigned int getNumberOfObjects() const override
Returns the number of objects in the container. In parallel code this practice is forbidden to avoid ...
Definition: ParticleHandler.cc:1325
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:37
Definition: Vector.h:51
void setWriteVTK(FileType)
Sets whether walls are written into a VTK file.
Definition: WallHandler.cc:467
const Mdouble pi
Definition: ExtendedMath.h:45
Mdouble cos(Mdouble x)
Definition: ExtendedMath.cc:64
Mdouble sin(Mdouble x)
Definition: ExtendedMath.cc:44
Definition: VerticalMixer.h:203
void addBlades() override
Definition: VerticalMixer.h:209
Mdouble bladeAngle_
Definition: VerticalMixer.h:207
void addPrettyBlades() override
Definition: VerticalMixer.h:234
VerticalMixerAngledBlades(int argc, char *argv[])
Definition: VerticalMixer.h:205
Definition: VerticalMixer.h:177
void addBlades() override
Definition: VerticalMixer.h:184
Mdouble bladeWidth_
Definition: VerticalMixer.h:181
VerticalMixerStraightBlades(int argc, char *argv[])
Definition: VerticalMixer.h:179
Mdouble bladeHeight_
Definition: VerticalMixer.h:182
Definition: VerticalMixer.h:33
Mdouble particleRadius_
Definition: VerticalMixer.h:37
bool prettyWalls_
Definition: VerticalMixer.h:43
Mdouble drumRadius_
Definition: VerticalMixer.h:38
void setupInitialConditions() override
This function allows to set the initial conditions for our problem to be solved, by default particle ...
Definition: VerticalMixer.h:46
VerticalMixer(int argc, char *argv[])
Definition: VerticalMixer.h:35
Vec3D angularVelocity
Definition: VerticalMixer.h:40
virtual void addPrettyBlades()
Definition: VerticalMixer.h:174
Mdouble drumLength_
Definition: VerticalMixer.h:39
Mdouble particleNumber_
Definition: VerticalMixer.h:41
void printTime() const override
Displays the current simulation time and the maximum simulation duration.
Definition: VerticalMixer.h:166
virtual void addBlades()
Definition: VerticalMixer.h:172
bool haveOuterWalls
Definition: VerticalMixer.h:44