MercuryDPM  0.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PeriodicBoundary.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 #ifndef PeriodicBoundary_H
27 #define PeriodicBoundary_H
28 
29 #include "BaseBoundary.h"
31 
36 public:
37 
38  virtual PeriodicBoundary* copy() const
39  {
40  #ifdef CONSTUCTOR_OUTPUT
41  std::cerr << "virtual PeriodicBoundary* copy() const finished" << std::endl;
42  #endif
43  return new PeriodicBoundary(*this);
44  }
45 
46 
52  void set(Vec3D normal_, Mdouble position_left_, Mdouble position_right_) {
53  // factor is used to set normal to unit length
54  factor = 1. / sqrt(Dot(normal_, normal_));
55  normal = normal_ * factor;
56  position_left = position_left_ * factor;
57  position_right = position_right_ * factor;
59  }
60 
63  void set(Vec3D normal_, Mdouble position_left_, Mdouble position_right_, Vec3D shift_direction) {
64  // factor is used to set normal to unit length
65  factor = 1. / sqrt(Dot(normal_, normal_));
66  normal = normal_ * factor;
67  position_left = position_left_ * factor;
68  position_right = position_right_ * factor;
69  // factor is used to set shift vector to correct length
70  factor = (position_right - position_left) * Dot(shift_direction, normal);
71  shift = shift_direction * factor;
72  }
73 
75  void move_left(Mdouble position_)
76  {
77  position_left=position_*factor;
79  }
80 
82  void move_right(Mdouble position_)
83  {
84  position_right=position_*factor;
86  }
87 
88 
97  return distance(P.get_Position());
98  }
99 
100  Mdouble distance(const Vec3D &P) {
101  Mdouble position = Dot(P, normal);
102 
103  if (position - position_left < position_right - position) {
104  left_wall = true;
105  return position - position_left;
106  } else {
107  left_wall = false;
108  return position_right - position;
109  }
110  }
111 
114  if (left_wall) {
115  F0->move(shift);
116  left_wall = false;
117  }
118  else {
119  F0->move(-shift);
120  left_wall = true;
121  }
122  }
123 
126  if (left_wall) {
127  return Position + shift;
128  }
129  else {
130  return Position - shift;
131  }
132  }
133 
135  void shift_positions(Vec3D &PI, Vec3D &PJ) {
136  if (left_wall) {
137  PI += shift;
138  PJ += shift;
139  left_wall = false;
140  }
141  else {
142  PI -= shift;
143  PJ -= shift;
144  left_wall = true;
145  }
146  }
147 
150  Mdouble PQdotn = Dot(P-Q, normal);
151  Mdouble shift_norm2 = shift.GetLength2();
152  //Check if P is so far from Q that a shift would move it closer
153  if (sqr(PQdotn) > .25 * shift_norm2) {
154  //Now determine the direction of the shift
155  if (PQdotn>0.0) P -= shift;
156  else P += shift;
157  }
158  }
159 
160 
162  void read(std::istream& is) {
163  std::string dummy;
164  is >> dummy >> normal >> dummy >> position_left >> dummy >> position_right >> dummy >> shift;
165  }
166 
168  void print(std::ostream& os) const {
169  os << "PeriodicBoundary normal " << normal
170  << " position_left " << position_left
171  << " position_right " << position_right
172  << " shift " << shift;
173  }
174 
175  Vec3D& get_normal() {return normal;}
176 
178  {
180  {
181  BaseParticle* F0=P->copy();
182  shift_position(F0);
183 
184  //If the Particle includes TangentalSprings reverse them
185  TangentialSpringParticle* TSParticle=dynamic_cast<TangentialSpringParticle*>(F0);
186  if(TSParticle)
187  TSParticle->reverseTangentialSprings();
188 
189  //If Particle is Mdouble shifted, get correct original particle
190  BaseParticle* From=P;
191  while(From->get_PeriodicFromParticle()!=NULL)
192  From=From->get_PeriodicFromParticle();
193  F0->set_periodicFromParticle(From);
194 
195  pH.addObject(F0);
196  return 1;
197  }
198  return 0;
199  }
200 
202  {
203  if (distance(*P)<0)
204  {
205  shift_position(P);
206  }
207  return false;
208  }
209 
210  private:
211  bool left_wall;
217 };
218 #endif
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
Mdouble get_InteractionRadius() const
void move_right(Mdouble position_)
Allows the right periodic wall to be moved to a new position and automatically changes its shift valu...
Mdouble position_left
position of left wall, s.t. normal*x=position_left
bool checkBoundaryAfterParticleMoved(BaseParticle *P, ParticleHandler &pH UNUSED)
BaseParticle * get_PeriodicFromParticle() const
#define sqr(a)
Definition: ExtendedMath.h:36
void set(Vec3D normal_, Mdouble position_left_, Mdouble position_right_, Vec3D shift_direction)
For general parallelogramic domains, the direction of the shift vector has to be set manually...
bool left_wall
true if closest wall is the left wall
friend Mdouble GetLength2(const Vec3D &A)
Definition: Vector.h:183
Defines a pair of periodic walls. The particles are in {x: position_left<=normal*x
void set_periodicFromParticle(BaseParticle *_new)
void read(std::istream &is)
reads wall
void print(std::ostream &os) const
outputs wall
void shift_positions(Vec3D &PI, Vec3D &PJ)
shifts two particles
Vec3D normal
outward unit normal vector for right wall
Mdouble distance(BaseParticle &P)
Returns the distance of the wall to the particle, and sets left_wall = true, if the left wall is the ...
Vec3D get_shifted_position(Vec3D &Position)
returns the shifted particle w/o actually shifting
double Mdouble
Definition: ExtendedMath.h:33
virtual PeriodicBoundary * copy() const
BaseBoundary copy method.
virtual void addObject(BaseParticle *P)
Adds a BaseParticle to the ParticleHandler.
Mdouble distance(const Vec3D &P)
void move(const Vec3D &_new)
void shift_position(BaseParticle *F0)
shifts the particle (after distance set the left_wall value)
const Vec3D & get_Position() const
Container to store all BaseParticle.
#define UNUSED
Definition: ExtendedMath.h:38
Mdouble factor
This is the normal to rescale to unit vectoers.
void set(Vec3D normal_, Mdouble position_left_, Mdouble position_right_)
Defines a periodic wall, given a normal vector s.t.
Mdouble position_right
position of right wall, s.t. normal*x=position_right
void move_left(Mdouble position_)
Allows the left periodic wall to be moved to a new position and automatically changes its shift value...
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:40
void get_close_together(Vec3D &P, Vec3D &Q)
shift P such that it is closest to Q
Vec3D shift
shift from left to right boundary
int createPeriodicParticles(BaseParticle *P, ParticleHandler &pH)
virtual BaseParticle * copy() const
Particle copy method. It calls to copy contrustor of this Particle, usefull for polymorfism.