MercuryDPM  0.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CircularPeriodicBoundary.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 CircularPeriodicBoundary_H
27 #define CircularPeriodicBoundary_H
28 
33 public:
34 
36  {
37  innerRadius=1.0;
38  #ifdef CONSTUCTOR_OUTPUT
39  std::cerr << "CircularPeriodicBoundary() finished" << std::endl;
40  #endif
41  }
42 
44  {
45  this->innerRadius=innerRadius;
46  #ifdef CONSTUCTOR_OUTPUT
47  std::cerr << "CircularPeriodicBoundary(double innerRadius) finished" << std::endl;
48  #endif
49  }
50 
52  {
53  #ifdef CONSTUCTOR_OUTPUT
54  std::cerr << "virtual CircularPeriodicBoundary* copy() const finished" << std::endl;
55  #endif
56  return new CircularPeriodicBoundary(*this);
57  }
58 
59  void rotateParticle(BaseParticle *P, double angle)
60  {
61  double R=sqrt(pow(P->get_Position().X,2)+pow(P->get_Position().Y,2));
62  double alphaPos=atan2(P->get_Position().Y,P->get_Position().X);
63  double V=sqrt(pow(P->get_Velocity().X,2)+pow(P->get_Velocity().Y,2));
64  double alphaVel=atan2(P->get_Velocity().Y,P->get_Velocity().X);
65  alphaPos+=angle;
66  alphaVel+=angle;
67 
68  P->set_Position(Vec3D(cos(alphaPos)*R,sin(alphaPos*R),P->get_Position().Z));
69  P->set_Velocity(Vec3D(cos(alphaVel)*V,sin(alphaVel*V),P->get_Velocity().Z));
71  }
72 
74  {
75  double R=sqrt(pow(P->get_Position().X,2)+pow(P->get_Position().Y,2));
76  double alpha=atan2(P->get_Position().Y,P->get_Position().X);
77  int i=log(R/innerRadius)/log(2.0)+1;
78  double pieSize=2.0/pow(2.0,i)*constants::pi;
79  int C=0;
80  //std::cout<<"R="<<R<<" alpha="<<alpha<<" i="<<i<<" pieSize="<<pieSize<<std::endl;
81 
82  //Check if the particle is close to it's inner Radius or is is close to zero alpha (small y)
84  {
85  //std::cout<<"Going to shift because "<<R-P->get_Radius()<<"<"<<pow(2,i-1)*innerRadius<<" or "<<P->get_Position().Y<<"<"<<P->get_Radius()<<std::endl;
86  //std::cout<<*P<<" has been shifted"<<std::endl;
87 
88  BaseParticle* F0=P->copy();
89  rotateParticle(F0,pieSize);
90 
91  //If Particle is Mdouble shifted, get correct original particle
92  BaseParticle* From=P;
93  while(From->get_PeriodicFromParticle()!=NULL)
94  From=From->get_PeriodicFromParticle();
95  F0->set_periodicFromParticle(From);
96 
97  //std::cout<<*F0<<" is the result"<<std::endl;
98  pH.addObject(F0);
99  C++;
100  }
101  //Check here only for i>0 becuase for i=1 they both give the same particle
102  if(i>1&&R*R*(1-pow(cos(alpha-pieSize),2))<P->get_InteractionRadius()+pH.getLargestParticle()->get_InteractionRadius())
103  {
104  //std::cout<<*P<<" has been shifted back"<<std::endl;
105 
106  BaseParticle* F0=P->copy();
107  rotateParticle(F0,-pieSize);
108 
109  //If Particle is Mdouble shifted, get correct original particle
110  BaseParticle* From=P;
111  while(From->get_PeriodicFromParticle()!=NULL)
112  From=From->get_PeriodicFromParticle();
113  F0->set_periodicFromParticle(From);
114 
115  //std::cout<<*F0<<" is the result"<<std::endl;
116  pH.addObject(F0);
117  C++;
118  }
119  return C;
120  }
121 
123  {
124  double R=sqrt(pow(P->get_Position().X,2)+pow(P->get_Position().Y,2));
125  double alpha=atan2(P->get_Position().Y,P->get_Position().X);
126  int i=log(R/innerRadius)/log(2.0)+1;
127  double pieSize=2.0/pow(2.0,i)*constants::pi;
128 
129  double oldR=sqrt(pow(P->get_Position().X-P->get_Displacement().X,2)+pow(P->get_Position().Y-P->get_Displacement().Y,2));
131  int oldI=log(oldR/innerRadius)/log(2.0)+1.0;
132 
133  if(i>0&&i>oldI) //Particle moves outward so it may have to be deleted
134  {
135  //std::cout<<"Particle="<<P->get_Index()<<" moving outward with alpha="<<alpha<<" and pieSize="<<pieSize<<" ";
136  if(alpha<0||alpha>pieSize)
137  {
138  if(alpha>2.0*pieSize)
139  {
140  //std::cout<<"and it is rotated into the pie"<<std::endl;
141  rotateParticle(P,-pieSize);
142  }
143  else
144  {
145  //Delete particle
146  //std::cout<<"and it should be deleted"<<std::endl;
147  pH.removeObject(P->get_Index());
148  return true;
149  }
150  }
151  //else
152  //std::cout<<"and nothing happens"<<std::endl;
153  }
154  else if (i>=0&&i<oldI) //Particle moves inward so it has to be coppied
155  {
156  //std::cout<<"Particle="<<P->get_Index()<<" moving inward and is thus coppied with alpha="<<alpha<<" and pieSize="<<pieSize<<std::endl;
157  //std::cout<<"i="<<i<<" oldI="<<oldI<<" R="<<R<<" oldR="<<oldR<<std::endl;
158  //std::cout<<"Position="<<P->get_Position()<<" Displacement="<<P->get_Displacement()<<std::endl;
159  BaseParticle* F0=P->copy();
160  F0->set_Displacement(Vec3D(0.0,0.0,0.0));
161  if(alpha<0)
162  {
163  rotateParticle(P,pieSize);
164  rotateParticle(F0,0.5*pieSize);
165  }
166  else if(alpha<0.5*pieSize)
167  {
168  rotateParticle(F0,0.5*pieSize);
169  }
170  else if(alpha<pieSize)
171  {
172  rotateParticle(F0,-0.5*pieSize);
173  }
174  else
175  {
176  rotateParticle(P,-pieSize);
177  rotateParticle(F0,-0.5*pieSize);
178  }
179  pH.addObject(F0);
180  }
181  else if(i>0&&alpha<0)
182  {
183  //std::cout<<"Particle="<<P->get_Index()<<" i="<<i<<" R="<<R<<" alpha="<<alpha<<" positive rotated pieSize="<<pieSize<<std::endl;
184  rotateParticle(P,pieSize);
185  }
186  else if(i>0&&alpha>pieSize)
187  {
188  //std::cout<<"Particle="<<P->get_Index()<<" i="<<i<<" R="<<R<<" alpha="<<alpha<<" negative rotated pieSize="<<pieSize<<std::endl;
189  rotateParticle(P,-pieSize);
190  }
191  return false;
192  }
193 
195  void read(std::istream& is) {
196  std::string dummy;
197  is >> dummy >> innerRadius;
198  }
199 
201  void print(std::ostream& os) const {
202  os << "CircularPeriodicBoundary innerRadius "<<innerRadius;
203  }
204 
205 
206 private:
207 
208  double innerRadius;
209 
210 
211  //A particle is between to Radii in plane (i) and has two (straight) walls (plane 0 defines centre)
212  //If it is close to its inner Radius it should be copied once with a positive rotation of 2*pi/2^i
213  //If it is close to one of its straight walls is should be rotative with +/- 2*pi/2^i
214 
215  //Particles can only apply forces to real particles
216 
217  //If a particle crosses a straight wall is should simply be shifted
218  //If a particle crosses its inner Radius it should be coppied
219  //If a particle crosses its outer Radius it may need to be deleted
220 
221 };
222 #endif
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
CircularPeriodicBoundary(double innerRadius)
Mdouble X
Definition: Vector.h:44
const Vec3D & get_Velocity() const
Mdouble get_InteractionRadius() const
CircularPeriodicBoundary * copy() const
BaseBoundary copy method.
BaseParticle * get_PeriodicFromParticle() const
int get_Index() const
Defines a pair of periodic walls. The particles are in {x: position_left<=normal*x
void set_periodicFromParticle(BaseParticle *_new)
void rotateParticle(BaseParticle *P, double angle)
void print(std::ostream &os) const
outputs wall
const Mdouble pi
Definition: ExtendedMath.h:54
int createPeriodicParticles(BaseParticle *P, ParticleHandler &pH)
virtual void addObject(BaseParticle *P)
Adds a BaseParticle to the ParticleHandler.
const Vec3D & get_Displacement() const
const Vec3D & get_Position() const
Container to store all BaseParticle.
void read(std::istream &is)
reads wall
Mdouble Y
Definition: Vector.h:44
void set_Velocity(const Vec3D &_new)
void set_Displacement(const Vec3D &_new)
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:40
virtual void removeObject(unsigned const int id)
Removes a Object from the BaseHandler.
Definition: BaseHandler.h:122
void set_Position(const Vec3D &_new)
Mdouble Z
Definition: Vector.h:44
virtual BaseParticle * copy() const
Particle copy method. It calls to copy contrustor of this Particle, usefull for polymorfism.
bool checkBoundaryAfterParticleMoved(BaseParticle *P, ParticleHandler &pH)