MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CircularPeriodicBoundary.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 
27 #include "ParticleHandler.h"
28 #include "Particles/BaseParticle.h"
29 
31  : BaseBoundary()
32 {
33  innerRadius_ = 1.0;
34 #ifdef DEBUG_CONSTRUCTOR
35  std::cout << "CircularPeriodicBoundary::CircularPeriodicBoundary() finished" << std::endl;
36 #endif
37 }
38 
40  : BaseBoundary()
41 {
42  this->innerRadius_ = innerRadius;
43 #ifdef DEBUG_CONSTRUCTOR
44  std::cout << "CircularPeriodicBoundary::CircularPeriodicBoundary(double innerRadius) finished" << std::endl;
45 #endif
46 }
47 
49 {
50  #ifdef DEBUG_DESTRUCTOR
51  std::cerr << "CircularPeriodicBoundary::~CircularPeriodicBoundary() finished" << std::endl;
52 #endif
53 }
54 
56 {
57 #ifdef DEBUG_CONSTRUCTOR
58  std::cerr << "CircularPeriodicBoundary::copy() const finished" << std::endl;
59 #endif
60  return new CircularPeriodicBoundary(*this);
61 }
62 
64 {
65  double R = sqrt(pow(P->getPosition().X, 2) + pow(P->getPosition().Y, 2));
66  double alphaPos = atan2(P->getPosition().Y, P->getPosition().X);
67  double V = sqrt(pow(P->getVelocity().X, 2) + pow(P->getVelocity().Y, 2));
68  double alphaVel = atan2(P->getVelocity().Y, P->getVelocity().X);
69  alphaPos += angle;
70  alphaVel += angle;
71 
72  P->setPosition(Vec3D(cos(alphaPos) * R, sin(alphaPos * R), P->getPosition().Z));
73  P->setVelocity(Vec3D(cos(alphaVel) * V, sin(alphaVel * V), P->getVelocity().Z));
75 }
76 
78 {
79  double R = sqrt(pow(P->getPosition().X, 2) + pow(P->getPosition().Y, 2));
80  double alpha = atan2(P->getPosition().Y, P->getPosition().X);
81  unsigned int i = static_cast<unsigned int>(std::floor(std::log(R / innerRadius_) / std::log(2.0))) + 1;
82  double pieSize = 2.0 / pow(2.0, i) * constants::pi;
83  //std::cout<<"R="<<R<<" alpha="<<alpha<<" i="<<i<<" pieSize="<<pieSize<<std::endl;
84 
85  //Check if the particle is close to it's inner Radius or is is close to zero alpha (small y)
86  if (i > 0 && (R - (P->getInteractionRadius() + pH.getLargestParticle()->getInteractionRadius()) < pow(2.0, i - 1) * innerRadius_ || P->getPosition().Y < (P->getInteractionRadius() + pH.getLargestParticle()->getInteractionRadius())))
87  {
88  //std::cout<<"Going to shift because "<<R-P->getRadius()<<"<"<<pow(2,i-1)*innerRadius<<" or "<<P->getPosition().Y<<"<"<<P->getRadius()<<std::endl;
89  //std::cout<<*P<<" has been shifted"<<std::endl;
90 
91  BaseParticle* F0 = P->copy();
92  rotateParticle(F0, pieSize);
93 
94  //If Particle is Mdouble shifted, get correct original particle
95  BaseParticle* From = P;
96  while (From->getPeriodicFromParticle() != nullptr)
97  From = From->getPeriodicFromParticle();
98  F0->setPeriodicFromParticle(From);
99 
100  //std::cout<<*F0<<" is the result"<<std::endl;
101  pH.addObject(F0);
102  }
103  //Check here only for i>0 becuase for i=1 they both give the same particle
104  if (i > 1 && R * R * (1 - pow(cos(alpha - pieSize), 2)) < P->getInteractionRadius() + pH.getLargestParticle()->getInteractionRadius())
105  {
106  //std::cout<<*P<<" has been shifted back"<<std::endl;
107 
108  BaseParticle* F0 = P->copy();
109  rotateParticle(F0, -pieSize);
110 
111  //If Particle is Mdouble shifted, get correct original particle
112  BaseParticle* From = P;
113  while (From->getPeriodicFromParticle() != nullptr)
114  From = From->getPeriodicFromParticle();
115  F0->setPeriodicFromParticle(From);
116 
117  //std::cout<<*F0<<" is the result"<<std::endl;
118  pH.addObject(F0);
119  }
120 }
121 
123 {
124  double R = sqrt(pow(P->getPosition().X, 2) + pow(P->getPosition().Y, 2));
125  double alpha = atan2(P->getPosition().Y, P->getPosition().X);
126  int i = static_cast<int>(std::floor(std::log(R / innerRadius_) / std::log(2.0))) + 1;
127  double pieSize = 2.0 / pow(2.0, i) * constants::pi;
128 
129  double oldR = sqrt(pow(P->getPosition().X - P->getDisplacement().X, 2) + pow(P->getPosition().Y - P->getDisplacement().Y, 2));
131  int oldI = static_cast<int>(std::floor(std::log(oldR / innerRadius_) / std::log(2.0))) + 1;
132 
133  if (i > 0 && i > oldI) //Particle moves outward so it may have to be deleted
134  {
135  //std::cout<<"Particle="<<P->getIndex()<<" 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->getIndex());
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->getIndex()<<" 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->getPosition()<<" Displacement="<<P->get_Displacement()<<std::endl;
159  BaseParticle* F0 = P->copy();
160  F0->setDisplacement(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->getIndex()<<" 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->getIndex()<<" i="<<i<<" R="<<R<<" alpha="<<alpha<<" negative rotated pieSize="<<pieSize<<std::endl;
189  rotateParticle(P, -pieSize);
190  }
191  return false;
192 }
193 
194 void CircularPeriodicBoundary::read(std::istream& is)
195 {
196  BaseBoundary::read(is);
197  std::string dummy;
198  is >> dummy >> innerRadius_;
199 }
200 
201 void CircularPeriodicBoundary::oldRead(std::istream& is)
202 {
203  std::string dummy;
204  is >> dummy >> innerRadius_;
205 }
206 
207 void CircularPeriodicBoundary::write(std::ostream& os) const
208  {
210  os << " innerRadius " << innerRadius_;
211 }
212 
214 {
215  return "CircularPeriodicBoundary";
216 }
virtual std::string getName() const
Returns the name of the object.
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:108
void write(std::ostream &os) const
outputs the CircularPeriodicBoundary
Mdouble X
the vector components
Definition: Vector.h:52
CircularPeriodicBoundary * copy() const
Used to create a copy of the object NB: purely virtual function.
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
virtual void removeObject(unsigned const int index)
Removes a BaseParticle from the ParticleHandler.
CircularPeriodicBoundary()
default constructor
void setDisplacement(const Vec3D &disp)
Sets the particle's displacement (= difference between current position and that of the previous time...
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 setPeriodicFromParticle(BaseParticle *p)
Assigns the pointer to the 'original' particle this one's a periodic copy of.
Mdouble log(Mdouble Power)
Definition: ExtendedMath.cc:97
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
used to create a circular periodic boundary
Mdouble cos(Mdouble x)
Definition: ExtendedMath.cc:60
void createPeriodicParticles(BaseParticle *P, ParticleHandler &pH)
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
void rotateParticle(BaseParticle *P, double angle)
const Vec3D & getDisplacement() const
Returns the particle's displacement relative to the previous time step.
Mdouble sin(Mdouble x)
Definition: ExtendedMath.cc:42
const Mdouble pi
Definition: ExtendedMath.h:42
virtual void addObject(BaseParticle *P)
Adds a BaseParticle to the ParticleHandler.
Container to store all BaseParticle.
void read(std::istream &is)
reads the CircularPeriodicBoundary
Mdouble Y
Definition: Vector.h:52
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
virtual const Vec3D & getVelocity() const
Returns the velocity of this interactable.
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
Mdouble Z
Definition: Vector.h:52
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
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, overriding the version of Base...
Definition: BaseBoundary.cc:67
bool checkBoundaryAfterParticleMoved(BaseParticle *P, ParticleHandler &pH)