MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LeesEdwardsBoundary.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2020, 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 "LeesEdwardsBoundary.h"
27 #include "ParticleHandler.h"
28 #include "Particles/BaseParticle.h"
29 #include "DPMBase.h"
30 
39 void
40 LeesEdwardsBoundary::set(std::function<Mdouble(Mdouble)> shift, std::function<Mdouble(Mdouble)> velocity, Mdouble left,
41  Mdouble right, Mdouble down, Mdouble up)
42 {
43  shift_ = shift;
44  velocity_ = velocity;
45  left_ = left;
46  right_ = right;
47  down_ = down;
48  up_ = up;
49 }
50 
52 {
53  left_ = left;
54  right_ = right;
55  down_ = down;
56  up_ = up;
57 }
58 
59 
64 void LeesEdwardsBoundary::read(std::istream& is)
65 {
66  std::string dummy;
68  Mdouble shift;
69  Mdouble velocity;
70  is >> dummy >> left_ >> dummy >> right_ >> dummy >> down_ >> dummy >> up_ >> dummy >> shift >> dummy >> velocity;
71  shift_ = [shift, velocity](Mdouble time UNUSED) { return shift + velocity * time; };
72  velocity_ = [velocity](Mdouble time UNUSED) { return velocity; };
73 }
74 
79 void LeesEdwardsBoundary::write(std::ostream& os) const
80 {
82  Mdouble time = getHandler()->getDPMBase()->getTime();
83  os << " left " << left_ << " right " << right_ << " down " << down_ << " up " << up_ << " shift " << shift_(time)
84  << " vel " << velocity_(time);
85 }
86 
90 std::string LeesEdwardsBoundary::getName() const
91 {
92  return "LeesEdwardsBoundary";
93 }
94 
100 {
101  return new LeesEdwardsBoundary(*this);
102 }
103 
111 {
112  Mdouble left = p.getPosition().X - left_;
113  Mdouble right = right_ - p.getPosition().X;
114  if (left < right)
115  {
116  positive = true;
117  return left;
118  }
119  else
120  {
121  positive = false;
122  return right;
123  }
124 }
125 
133 {
134  Mdouble down = p.getPosition().Y - down_;
135  Mdouble up = up_ - p.getPosition().Y;
136  if (down < up)
137  {
138  positive = true;
139  return down;
140  }
141  else
142  {
143  positive = false;
144  return up;
145  }
146 }
147 
156 {
157  if (positive)
158  {
159  p->move(Vec3D(right_ - left_, 0.0, 0.0));
160  }
161  else
162  {
163  p->move(Vec3D(left_ - right_, 0.0, 0.0));
164  }
165 }
166 
175 {
176  Mdouble time = getHandler()->getDPMBase()->getTime();
177  if (positive)
178  {
179  p->move(Vec3D(shift_(time), up_ - down_, 0.0));
180  p->addVelocity(Vec3D(velocity_(time), 0.0, 0.0));
181  }
182  else
183  {
184  p->move(Vec3D(-shift_(time), down_ - up_, 0.0));
185  p->addVelocity(Vec3D(-velocity_(time), 0.0, 0.0));
186  }
187 }
188 
198 {
199  bool positive; // TRUE if the particle is closest to the left boundary
200  // wall (set by getVerticalDistance in the following if-statement)
201  // check if particle is close enough to either of the walls
203  if (getHorizontalDistance(*p, positive) < maxDistance)
204  {
205  // create a periodic copy of the particle
206  BaseParticle* F0 = p->copy();
207  pH.addObject(F0);
209 
210  // If Particle is doubly shifted, get correct original particle
211  BaseParticle* From = p;
212  while (From->getPeriodicFromParticle() != nullptr)
213  From = From->getPeriodicFromParticle();
214  F0->setPeriodicFromParticle(From);
215 
216  // shift the copy to the 'periodic' position
217  shiftHorizontalPosition(F0, positive);
218 
219  // NB: No extra creation of possible vertical copies of the horizontal copy
220  // here (as compared to createVerticalPeriodicParticles), because these would
221  // overlap with the extra creation of horizontal copies in createVerticalPeriodicParticles.
222  }
223 }
224 
234 {
235  bool positive; // TRUE if the particle is closest to the bottom boundary
236  // wall (set by getVerticalDistance in the following if-statement)
237  // check if particle is close enough to either of the walls
239  if (getVerticalDistance(*p, positive) < maxDistance)
240  {
241  // create a periodic copy of the particle
242  BaseParticle* F0 = p->copy();
243  pH.addObject(F0);
245 
246  // If Particle is doubly shifted, get correct original particle
247  BaseParticle* From = p;
248  while (From->getPeriodicFromParticle() != nullptr)
249  From = From->getPeriodicFromParticle();
250  F0->setPeriodicFromParticle(From);
251 
252  // shift the copy to the 'periodic' position
253  shiftVerticalPosition(F0, positive);
254  while (getHorizontalDistance(*F0, positive) < 0)
255  {
256  shiftHorizontalPosition(F0, positive);
257  }
258 
259  // Create horizontal periodic copies of the copy particle, if needed (i.e.,
260  // if the original particle is in one of the boundary corners).
262  }
263 }
264 
271 {
274 }
275 
277 {
278  unsigned numberOfParticles = pH.getSize();
279  for (unsigned i = 0; i < numberOfParticles; i++)
280  {
282  }
283 }
284 
291 {
292  bool positive;
293  while (getVerticalDistance(*p, positive) < 0)
294  {
295  shiftVerticalPosition(p, positive);
296  }
297  while (getHorizontalDistance(*p, positive) < 0)
298  {
299  shiftHorizontalPosition(p, positive);
300  }
301 }
302 
304 {
305  for (auto p = pH.begin(); p != pH.end(); ++p)
306  {
308  }
309 }
310 
311 
313 {
314  Mdouble time = getHandler()->getDPMBase()->getTime();
315  return shift_(time);
316 }
317 
319 {
320  Mdouble time = getHandler()->getDPMBase()->getTime();
321  return velocity_(time);
322 }
323 
324 void LeesEdwardsBoundary::setShift(std::function<Mdouble(Mdouble)> shift)
325 {
326  shift_ = shift;
327 }
328 
329 void LeesEdwardsBoundary::setVelocity(std::function<Mdouble(Mdouble)> velocity)
330 {
331  velocity_ = velocity;
332 }
BaseParticle * getLargestParticle() const
Returns the pointer of the largest particle in the particle handler. When mercury is running in paral...
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Mdouble X
the vector components
Definition: Vector.h:65
Class which creates a boundary with Lees-Edwards type periodic boundary conditions.
void addVelocity(const Vec3D &velocity)
adds an increment to the velocity.
void addObject(BaseParticle *P) override
Adds a BaseParticle to the ParticleHandler.
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655
double Mdouble
Definition: GeneralDefine.h:34
Mdouble getMaxInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
Definition: BaseParticle.h:359
LeesEdwardsBoundary * copy() const override
Creates a copy of the object.
std::function< Mdouble(Mdouble)> shift_
(signed) Vertical distance between the top wall and the origin
void createPeriodicParticle(BaseParticle *p, ParticleHandler &pH) override
const std::complex< Mdouble > i
Definition: ExtendedMath.h:50
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:704
void setVelocity(std::function< Mdouble(Mdouble)>)
void setPeriodicFromParticle(BaseParticle *p)
Assigns the pointer to the 'original' particle this one's a periodic copy of (used in periodic bounda...
Definition: BaseParticle.h:438
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
Definition: BaseParticle.h:338
void read(std::istream &is) override=0
Reads the object's id_ from given istream NB: purely virtual function, overriding the version of Base...
Definition: BaseBoundary.cc:61
virtual BaseParticle * copy() const =0
Particle copy method. It calls to copy constructor of this Particle, useful for polymorfism.
void createPeriodicParticles(ParticleHandler &pH) override
Creates horizontal and vertical periodic copies of given particle, if needed.
void read(std::istream &is) override
Reads all boundary properties from a stream.
void createHorizontalPeriodicParticles(BaseParticle *p, ParticleHandler &pH)
Creates horizontal periodic copies of given particle, if needed.
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:690
std::function< Mdouble(Mdouble)> velocity_
void shiftVerticalPosition(BaseParticle *p, bool positive)
Applies a vertical shift to the given particle.
void updateBoundaries(Mdouble left, Mdouble right, Mdouble down, Mdouble up)
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:613
void setShift(std::function< Mdouble(Mdouble)>)
Mdouble up_
(signed) Vertical distance between the bottom wall and the origin
void createVerticalPeriodicParticles(BaseParticle *p, ParticleHandler &pH)
Creates vertical periodic copies of given particle, if needed.
void checkBoundaryAfterParticleMoved(BaseParticle *p)
Checks if particle crossed a boundary wall and if so, applies periodic shift.
#define UNUSED
Definition: GeneralDefine.h:39
void write(std::ostream &os) const override=0
Adds object's id_ to given ostream NB: purely virtual function, overriding the version of BaseObject...
Definition: BaseBoundary.cc:70
BoundaryHandler * getHandler() const
Returns the boundary's BoundaryHandler.
Mdouble down_
(signed) Horizontal distance between the right wall and the origin
void copyInteractionsForPeriodicParticles(const BaseInteractable &p)
Copies interactions to this BaseInteractable whenever a periodic copy made.
void write(std::ostream &os) const override
Writes all boundary properties to a stream.
Container to store all BaseParticle.
Mdouble Y
Definition: Vector.h:65
void shiftHorizontalPosition(BaseParticle *p, bool positive)
Applies a horizontal shift to the given particle.
void checkBoundaryAfterParticlesMove(ParticleHandler &pH) override
Checks if particles need to be adjusted after their position has been updated.
Mdouble right_
(signed) Horizontal distance between the left wall and the origin
void set(std::function< Mdouble(Mdouble)> shift, std::function< Mdouble(Mdouble)> velocity, Mdouble left, Mdouble right, Mdouble down, Mdouble up)
Sets all boundary properties.
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:634
Definition: Vector.h:49
virtual void move(const Vec3D &move)
Moves this BaseInteractable by adding an amount to the position.
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:725
Mdouble getTime() const
Returns the current simulation time.
Definition: DPMBase.cc:797
Mdouble getHorizontalDistance(BaseParticle &p, bool &positive)
Returns distance from given particle to the closest horizontal wall.
std::string getName() const override
Returns the name of the object.
Mdouble getVerticalDistance(BaseParticle &p, bool &positive)
Returns distance from given particle to the closest vertical wall.