MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PeriodicBoundary.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 "PeriodicBoundary.h"
27 #include "ParticleHandler.h"
28 #include "Particles/BaseParticle.h"
29 
34  : BaseBoundary()
35 {
37  distanceLeft_ = std::numeric_limits<double>::quiet_NaN();
38  distanceRight_= std::numeric_limits<double>::quiet_NaN();
39  scaleFactor_= std::numeric_limits<double>::quiet_NaN();
40 
41 #ifdef DEBUG_CONSTRUCTOR
42  std::cout<<"PeriodicBoundary::PeriodicBoundary() finished"<<std::endl;
43 #endif
44 }
45 
50 {
51 #ifdef DEBUG_DESTRUCTOR
52  std::cout<<"PeriodicBoundary::~PeriodicBoundary() finished"<<std::endl;
53 #endif
54 }
55 
60 {
61  return new PeriodicBoundary(*this);
62 }
63 
72 void PeriodicBoundary::set(Vec3D normal, Mdouble distanceLeft, Mdouble distanceRight)
73 {
74  // factor is used to set normal to unit length
75  scaleFactor_ = 1. / std::sqrt(Vec3D::dot(normal, normal));
76  normal_ = normal * scaleFactor_;
77  distanceLeft_ = distanceLeft * scaleFactor_;
78  distanceRight_ = distanceRight * scaleFactor_;
80 }
81 
91 void PeriodicBoundary::set(Vec3D normal, Mdouble distanceLeft, Mdouble distanceRight, Vec3D shiftDirection)
92 {
93  // factor is used to set normal to unit length
94  scaleFactor_ = 1. / std::sqrt(Vec3D::dot(normal, normal));
95  normal_ = normal * scaleFactor_;
96  distanceLeft_ = distanceLeft * scaleFactor_;
97  distanceRight_ = distanceRight * scaleFactor_;
98  // factor is used to set shift vector to correct length
99  scaleFactor_ = (distanceRight_ - distanceLeft_) * Vec3D::dot(shiftDirection, normal_);
100  shift_ = shiftDirection * scaleFactor_;
101 }
109 {
110  distanceLeft_ = distanceLeft * scaleFactor_;
112 }
113 
121 {
122  distanceRight_ = distanceRight * scaleFactor_;
124 }
125 
135 {
136  return getDistance(p.getPosition());
137 }
138 
146 {
147  Mdouble distance = Vec3D::dot(position, normal_);
148 
149  if (distance - distanceLeft_ < distanceRight_ - distance)
150  {
151  closestToLeftBoundary_ = true;
152  return distance - distanceLeft_;
153  }
154  else
155  {
156  closestToLeftBoundary_ = false;
157  return distanceRight_ - distance;
158  }
159 }
160 
179 {
181  {
182  p->move(shift_);
183  closestToLeftBoundary_ = false;
184  }
185  else
186  {
187  p->move(-shift_);
188  closestToLeftBoundary_ = true;
189  }
190 }
191 
192 /*
193  Vec3D PeriodicBoundary::getShiftedPosition(Vec3D &position)
194  {
195  if (left_wall)
196  {
197  return position + shift_;
198  }
199  else
200  {
201  return position - shift_;
202  }
203  }
204  */
205 
212 void PeriodicBoundary::shiftPositions(Vec3D& position1, Vec3D& position2)
213 {
215  {
216  position1 += shift_;
217  position2 += shift_;
218  closestToLeftBoundary_ = false;
219  }
220  else
221  {
222  position1 -= shift_;
223  position2 -= shift_;
224  closestToLeftBoundary_ = true;
225  }
226 }
227 \
228 /*
229  * \details Returns TRUE if last particle/position checked is closest to the 'left'
230  * wall, and FALSE if it is closest to the 'right' wall.
231  * \return value of closestToLeftBoundary_ data member
232  */
234 {
235  return closestToLeftBoundary_;
236 }
237 
238 /*
239  void PeriodicBoundary::getCloseTogether(Vec3D &P, Vec3D &Q)
240  {
241  Mdouble PQdotn = Vec3D::Dot(P - Q, normal_);
242  Mdouble shift_norm2 = shift.GetLength2();
243  //Check if P is so far from Q that a shift would move it closer
244  if (mathsFunc::square(PQdotn) > .25 * shift_norm2)
245  {
246  //Now determine the direction of the shift
247  if (PQdotn > 0.0)
248  P -= shift;
249  else
250  P += shift;
251  }
252  }
253  */
254 
259 void PeriodicBoundary::read(std::istream& is)
260 {
261  BaseBoundary::read(is);
262  std::string dummy;
263  is >> dummy >> normal_
264  >> dummy >> scaleFactor_
265  >> dummy >> distanceLeft_
266  >> dummy >> distanceRight_
267  >> dummy >> shift_;
268 }
269 
274 void PeriodicBoundary::oldRead(std::istream& is)
275 {
276  std::string dummy;
277  is >> dummy >> normal_
278  >> dummy >> scaleFactor_
279  >> dummy >> distanceLeft_
280  >> dummy >> distanceRight_
281  >> dummy >> shift_;
282 }
283 
288 void PeriodicBoundary::write(std::ostream& os) const
289  {
291  os << " normal " << normal_
292  << " scaleFactor " << scaleFactor_
293  << " distanceLeft " << distanceLeft_
294  << " distanceRight " << distanceRight_
295  << " shift " << shift_;
296 }
297 
302 std::string PeriodicBoundary::getName() const
303 {
304  return "PeriodicBoundary";
305 }
306 
307 /*
308  Vec3D& PeriodicBoundary::getNormal()
309  {
310  return normal_;
311  }
312  */
313 
327 {
329  {
330  //Step 1: Copy the particle to new ghost particle.
331  BaseParticle* pGhost = p->copy();
332 
333  //Step 2: Copy the interactions of the ghost particle.
335 
336  //Step 3: Shift the ghost to the 'reflected' location.
337  shiftPosition(pGhost);
338 
339  //Step 4: If Particle is double shifted, get correct original particle
340  BaseParticle* from = p;
341  while (from->getPeriodicFromParticle() != nullptr)
342  from = from->getPeriodicFromParticle();
343  pGhost->setPeriodicFromParticle(from);
344 
345  pH.addObject(pGhost);
346  }
347 }
348 
359 {
360  if (getDistance(*p) < 0)
361  {
362  shiftPosition(p);
363  }
364  return false;
365 }
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
Mdouble getDistance(BaseParticle &p)
Returns the distance of the wall to the particle.
void set(Vec3D normal, Mdouble distanceLeft, Mdouble distanceRight)
Defines a periodic wall.
bool closestToLeftBoundary_
true if closest wall is the left wall
void shiftPosition(BaseParticle *p)
shifts the particle
MERCURY_DEPRECATED void oldRead(std::istream &is)
deprecated version of CubeInsertionBoundary::read().
void write(std::ostream &os) const =0
Adds object's id_ to given ostream NB: purely virtual function.
Definition: BaseBoundary.cc:76
double Mdouble
Mdouble scaleFactor_
This is the normal to rescale the normal vector to a unit vectors.
void createPeriodicParticles(BaseParticle *p, ParticleHandler &pH)
Checks distance of particle to closest wall and creates periodic copy if necessary.
void setPeriodicFromParticle(BaseParticle *p)
Assigns the pointer to the 'original' particle this one's a periodic copy of.
void moveRight(Mdouble distanceRight)
Sets the distance from the origin of the 'right' periodic wall.
void write(std::ostream &os) const
writes boundary properties to ostream
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:187
Mdouble distanceRight_
position of right wall, s.t. normal*x=position_right
PeriodicBoundary()
default constructor
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Vec3D normal_
outward unit normal vector for right wall
~PeriodicBoundary()
destructor
Defines a pair of periodic walls. Inherits from BaseBoundary.
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
bool checkBoundaryAfterParticleMoved(BaseParticle *p, ParticleHandler &pH UNUSED)
Checks if particle has crossed either boundary wall, and applies a shift if that is the case...
void read(std::istream &is)
reads boundary properties from istream
void moveLeft(Mdouble distanceLeft)
Sets the distance from the origin of the 'left' periodic wall.
virtual void addObject(BaseParticle *P)
Adds a BaseParticle to the ParticleHandler.
#define UNUSED
Definition: GeneralDefine.h:37
bool isClosestToLeftBoundary() const
Returns TRUE if last particle/position checked is closest to the 'left' wall, and FALSE if it is clos...
Mdouble distanceLeft_
position of left wall, s.t. normal*x=position_left
void copyInteractionsForPeriodicParticles(const BaseInteractable &p)
Copies interactions to this BaseInteractable whenever a periodic copy made.
Container to store all BaseParticle.
Vec3D shift_
shift from left to right boundary
void shiftPositions(Vec3D &postition1, Vec3D &postion2)
shifts two positions
PeriodicBoundary * copy() const
copy method
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.
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
virtual std::string getName() const
Returns the name of the object.
virtual BaseParticle * copy() const
Particle copy method. It calls to copy constructor of this Particle, useful for polymorfism.
void read(std::istream &is)=0
Reads the object's id_ from given istream NB: purely virtual function.
Definition: BaseBoundary.cc:67