MercuryDPM  Alpha
 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-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 "LeesEdwardsBoundary.h"
27 #include "ParticleHandler.h"
28 #include "Particles/BaseParticle.h"
29 #include "DPMBase.h"
30 
39 void LeesEdwardsBoundary::set(std::function<double (double)> shift, std::function<double (double)> velocity, Mdouble left, Mdouble right, Mdouble down, Mdouble up)
40 {
41  shift_ = shift;
42  velocity_ = velocity;
43  left_ = left;
44  right_ = right;
45  down_ = down;
46  up_ = up;
47 }
48 
53 void LeesEdwardsBoundary::read(std::istream& is)
54 {
55  std::string dummy;
57  Mdouble shift;
58  Mdouble velocity;
59  is>>dummy>>left_>>dummy>>right_>>dummy>>down_>>dummy>>up_>>dummy>>shift>>dummy>>velocity;
60  shift_=[shift,velocity] (double time UNUSED) { return shift+velocity*time;};
61  velocity_=[velocity] (double time UNUSED) {return velocity;};
62 }
63 
68 void LeesEdwardsBoundary::write(std::ostream& os) const
69 {
71  Mdouble time = getHandler()->getDPMBase()->getTime();
72  os<<" left "<<left_<<" right "<<right_<<" down "<<down_<<" up "<<up_<<" shift "<<shift_(time)<<" vel "<<velocity_(time);
73 }
74 
78 std::string LeesEdwardsBoundary::getName() const
79 {
80  return "LeesEdwardsBoundary";
81 }
82 
88 {
89  return new LeesEdwardsBoundary(*this);
90 }
91 
99 {
100  Mdouble left = p.getPosition().X - left_;
101  Mdouble right = right_ - p.getPosition().X;
102  if (left < right)
103  {
104  positive = true;
105  return left;
106  } else
107  {
108  positive = false;
109  return right;
110  }
111 }
112 
120 {
121  Mdouble down = p.getPosition().Y - down_;
122  Mdouble up = up_ - p.getPosition().Y;
123  if (down < up)
124  {
125  positive = true;
126  return down;
127  } else
128  {
129  positive = false;
130  return up;
131  }
132 }
133 
142 {
143  if (positive)
144  {
145  p->move(Vec3D(right_ - left_, 0.0, 0.0));
146  } else
147  {
148  p->move(Vec3D(left_ - right_, 0.0, 0.0));
149  }
150 }
151 
160 {
161  Mdouble time = getHandler()->getDPMBase()->getTime();
162  if (positive)
163  {
164  p->move(Vec3D(shift_(time), up_ - down_, 0.0));
165  p->addVelocity(Vec3D(velocity_(time), 0.0, 0.0));
166  } else
167  {
168  p->move(Vec3D(-shift_(time), down_ - up_, 0.0));
169  p->addVelocity(Vec3D(-velocity_(time), 0.0, 0.0));
170  }
171 }
172 
182 {
183  bool positive; // TRUE if the particle is closest to the left boundary
184  // wall (set by getVerticalDistance in the following if-statement)
185  // check if particle is close enough to either of the walls
187  {
188  // create a periodic copy of the particle
189  BaseParticle* F0 = p->copy();
190  pH.addObject(F0);
192 
193  // If Particle is doubly shifted, get correct original particle
194  BaseParticle* From = p;
195  while (From->getPeriodicFromParticle() != nullptr)
196  From = From->getPeriodicFromParticle();
197  F0->setPeriodicFromParticle(From);
198 
199  // shift the copy to the 'periodic' position
200  shiftHorizontalPosition(F0, positive);
201 
202  // NB: No extra creation of possible vertical copies of the horizontal copy
203  // here (as compared to createVerticalPeriodicParticles), because these would
204  // overlap with the extra creation of horizontal copies in createVerticalPeriodicParticles.
205  }
206 }
207 
217 {
218  bool positive; // TRUE if the particle is closest to the bottom boundary
219  // wall (set by getVerticalDistance in the following if-statement)
220  // check if particle is close enough to either of the walls
222  {
223  // create a periodic copy of the particle
224  BaseParticle* F0 = p->copy();
225  pH.addObject(F0);
227 
228  // If Particle is doubly shifted, get correct original particle
229  BaseParticle* From = p;
230  while (From->getPeriodicFromParticle() != nullptr)
231  From = From->getPeriodicFromParticle();
232  F0->setPeriodicFromParticle(From);
233 
234  // shift the copy to the 'periodic' position
235  shiftVerticalPosition(F0, positive);
236  while (getHorizontalDistance(*F0, positive) < 0)
237  {
238  shiftHorizontalPosition(F0, positive);
239  }
240 
241  // Create horizontal periodic copies of the copy particle, if needed (i.e.,
242  // if the original particle is in one of the boundary corners).
244  }
245 }
246 
253 {
256 }
257 
264 {
265  bool positive;
266  while (getVerticalDistance(*p, positive) < 0)
267  {
268  shiftVerticalPosition(p, positive);
269  }
270  while (getHorizontalDistance(*p, positive) < 0)
271  {
272  shiftHorizontalPosition(p, positive);
273  }
274  return false;
275 }
276 
277 
279 {
280  Mdouble time = getHandler()->getDPMBase()->getTime();
281  return shift_(time);
282 }
283 
285 {
286  Mdouble time = getHandler()->getDPMBase()->getTime();
287  return velocity_(time);
288 }
289 
290 void LeesEdwardsBoundary::setShift(std::function<double (double)> shift)
291 {
292  shift_ = shift;
293 }
294 
295 void LeesEdwardsBoundary::setVelocity(std::function<double (double)> velocity)
296 {
297  velocity_ = velocity;
298 }
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
std::function< double(double)> shift_
(signed) Vertical distance between the top wall and the origin
void setShift(std::function< double(double)>)
Mdouble X
the vector components
Definition: Vector.h:52
void set(std::function< double(double)> shift, std::function< double(double)> velocity, Mdouble left, Mdouble right, Mdouble down, Mdouble up)
Sets all boundary properties.
Class which creates a boundary with Lees-Edwards type periodic boundary conditions.
void addVelocity(const Vec3D &velocity)
adds an increment to the velocity.
std::function< double(double)> velocity_
void write(std::ostream &os) const =0
Adds object's id_ to given ostream NB: purely virtual function, overriding the version of BaseObject...
Definition: BaseBoundary.cc:76
void setVelocity(std::function< double(double)>)
double Mdouble
void createPeriodicParticles(BaseParticle *p, ParticleHandler &pH)
Creates horizontal and vertical periodic copies of given particle, if needed.
void setPeriodicFromParticle(BaseParticle *p)
Assigns the pointer to the 'original' particle this one's a periodic copy of.
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
void createHorizontalPeriodicParticles(BaseParticle *p, ParticleHandler &pH)
Creates horizontal periodic copies of given particle, if needed.
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
virtual std::string getName() const
Returns the name of the object.
void shiftVerticalPosition(BaseParticle *p, bool positive)
Applies a vertical shift to the given particle.
Mdouble up_
(signed) Vertical distance between the bottom wall and the origin
virtual void addObject(BaseParticle *P)
Adds a BaseParticle to the ParticleHandler.
void createVerticalPeriodicParticles(BaseParticle *p, ParticleHandler &pH)
Creates vertical periodic copies of given particle, if needed.
#define UNUSED
Definition: GeneralDefine.h:39
BoundaryHandler * getHandler() const
Returns the boundary's BoundaryHandler.
Mdouble down_
(signed) Horizontal distance between the right wall and the origin
void write(std::ostream &os) const
Writes all boundary properties to a stream.
void copyInteractionsForPeriodicParticles(const BaseInteractable &p)
Copies interactions to this BaseInteractable whenever a periodic copy made.
Container to store all BaseParticle.
Mdouble Y
Definition: Vector.h:52
void shiftHorizontalPosition(BaseParticle *p, bool positive)
Applies a horizontal shift to the given particle.
bool checkBoundaryAfterParticleMoved(BaseParticle *p, ParticleHandler &pH UNUSED)
Checks if particle crossed a boundary wall and if so, applies periodic shift.
LeesEdwardsBoundary * copy() const
Creates a copy of the object.
Mdouble right_
(signed) Horizontal distance between the left wall and the origin
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:473
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
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:543
void read(std::istream &is)
Reads all boundary properties from a stream.
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
Mdouble getTime() const
Access function for the time.
Definition: DPMBase.cc:169
Mdouble getHorizontalDistance(BaseParticle &p, bool &positive)
Returns distance from given particle to the closest horizontal wall.
virtual BaseParticle * copy() const
Particle copy method. It calls to copy constructor of this Particle, useful for polymorfism.
Mdouble getVerticalDistance(BaseParticle &p, bool &positive)
Returns distance from given particle to the closest vertical wall.
void read(std::istream &is)=0
Reads the object's id_ from given istream NB: purely virtual function, overriding the version of Base...
Definition: BaseBoundary.cc:67