MercuryDPM  0.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Screw.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 SCREW_H
27 #define SCREW_H
28 
29 #include "BaseWall.h"
30 #include "ExtendedMath.h"
31 
32 
34 
39 
40 
41 class Screw : public BaseWall
42 {
43  public:
44 
46  {
47  Start.set_zero();
48  L=1;
49  MaxR=1;
50  N=1;
51  omega=1;
52  offset=0;
53  thickness=0;
54  #ifdef CONSTUCTOR_OUTPUT
55  std::cerr << "Screw() finished" << std::endl;
56  #endif
57  }
58 
59  Screw(Vec3D Start, double L, double R, double N, double omega,double thickness) : BaseWall()
60  {
61  this->Start=Start;
62  this->L=L;
63  this->MaxR=R;
64  this->N=N;
65  this->omega=omega;
66  this->thickness=thickness;
67  this->offset=0.0;
68  #ifdef CONSTUCTOR_OUTPUT
69  std::cerr << "Screw() finished" << std::endl;
70  #endif
71  }
72 
73  virtual Screw* copy() const
74  {
75  return new Screw(*this);
76  }
77 
78  bool get_distance_and_normal(BaseParticle &P, Mdouble &distance, Vec3D &normal_return)
79  {
80  double Rsqr=pow(P.get_Position().X-Start.X,2)+pow(P.get_Position().Y-Start.Y,2);
82  {
83  //std::cout<<"Particle is out of first bound checking"<<std::endl;
84  //std::cout<<"Rule 1: "<<Rsqr<<"<"<<pow(r+P.get_Radius()+thickness,2)<<std::endl;
85  //std::cout<<"Rule 2: "<<Start.Z-P.get_Radius()-thickness<<"<"<<P.get_Position().Z<<"<"<<L+Start.Z+P.get_Radius()+thickness<<std::endl;
86  return false;
87  }
88  double R=sqrt(Rsqr);
89  double alpha=atan2(P.get_Position().Y-Start.Y,P.get_Position().X-Start.X);
90  double dz=P.get_Position().Z-Start.Z;
91 
96 
100 
104 
108 
109  double q; //Current guess
110  double dd; //Derivative at current guess
111  double ddd; //Second derivative at current guess
112  double q0=dz/L; //Minimum of the parabolic part
113 
118 
119  double k=round(alpha/constants::pi-2.0*(offset+N*q0));
120  q=alpha/(2.0*constants::pi*N)-k/(2.0*N)-offset/N;
121 
122  //Now apply Newton's method
123  do
124  {
125  dd =-2.0*Rsqr*constants::pi*N*sin(2.0*alpha-4.0*constants::pi*(N*q+offset))-2.0*L*(dz-q*L);
126  ddd= 8.0*Rsqr*constants::sqr_pi*N*N*cos(2.0*alpha-4.0*constants::pi*(N*q+offset))+2.0*L*L;
127  q-=dd/ddd;
128  } while(fabs(dd/ddd)>1e-14);
129 
130  //Calculate r
131  double r=R*cos(2.0*constants::pi*(offset+N*q)-alpha);
132 
133  //Check if the location is actually on the screw:
134  //First posibility is that the radius is to large:
135  if(fabs(r)>MaxR) //Left boundary of the coil
136  {
137  r=mathsFunc::sign(r)*MaxR;
138  int steps=0;
139  //This case reduces to the coil problem
140  do
141  {
142  dd =-4.0*R*r*constants::pi *N *sin(alpha-2.0*constants::pi*(N*q+offset))-2.0*L*(dz-q*L);
143  ddd= 8.0*R*r*constants::sqr_pi*N*N*cos(alpha-2.0*constants::pi*(N*q+offset))+2.0*L*L;
144  q-=dd/ddd;
145  steps++;
146  } while(fabs(dd/ddd)>1e-14);
147  }
148  //Second possibility is that it occured before the start of after the end
149  if(q<0)
150  {
151  q=0;
152  r=R*cos(alpha-2.0*constants::pi*(offset+q*N));
153  if(fabs(r)>MaxR)
154  {
155  r=mathsFunc::sign(r)*MaxR;
156  }
157  }
158  else if(q>1)
159  {
160  q=1;
161  r=R*cos(alpha-2.0*constants::pi*(offset+q*N));
162  if(fabs(r)>MaxR)
163  {
164  r=mathsFunc::sign(r)*MaxR;
165  }
166  }
167 
168  distance=R*R*pow(sin(alpha-2*constants::pi*(offset+N*q)),2)+pow(dz-q*L,2);
169  //If distance is to large there is no contact
171  {
172  return false;
173  }
174 
175  Vec3D ContactPoint;
176  distance=sqrt(distance)-thickness;
177  ContactPoint.X=Start.X+r*cos(2.0*constants::pi*(offset+N*q));
178  ContactPoint.Y=Start.Y+r*sin(2.0*constants::pi*(offset+N*q));
179  ContactPoint.Z=Start.Z+q*L;
180  normal_return=ContactPoint-P.get_Position();
181  normal_return/=normal_return.GetLength();
182  return true;
183  }
184 
187  {
188  offset+=omega*dt;
189  }
190 
192  void read(std::istream& is)
193  {
194  std::string dummy;
195  is >> dummy >> Start >> dummy >> L >> dummy >> MaxR >> dummy >> N >> dummy >> omega >> dummy >> offset;
196  }
197 
199  void print(std::ostream& os) const
200  {
201  os << "Screw start " << Start << " Length "<<L<<" Radius "<<MaxR<<" Revolutions "<<N<<" Omega "<<omega<<" Thickness "<<thickness<<" Offset "<<offset;
202  }
203 
205  Vec3D get_Velocity() const {return Vec3D(0.0,0.0,0.0);}
206 
207  private:
210 };
211 
212 #endif
virtual Screw * copy() const
Definition: Screw.h:73
Mdouble X
Definition: Vector.h:44
Vec3D Start
Definition: Screw.h:208
This function defines a archimedes screw in the z-direction from a (constant) starting point...
Definition: Screw.h:41
double L
Definition: Screw.h:209
bool get_distance_and_normal(BaseParticle &P, Mdouble &distance, Vec3D &normal_return)
Definition: Screw.h:78
int sign(T val)
This is a sign function, it returns -1 for negative numbers, 1 for positive numbers and 0 for 0...
Definition: ExtendedMath.h:75
void move_time(Mdouble dt)
Allows the wall to be moved to a new position (also orthogonal to the normal), and setting the veloci...
Definition: Screw.h:186
double offset
Definition: Screw.h:209
Screw(Vec3D Start, double L, double R, double N, double omega, double thickness)
Definition: Screw.h:59
const Mdouble pi
Definition: ExtendedMath.h:54
double Mdouble
Definition: ExtendedMath.h:33
void read(std::istream &is)
reads wall
Definition: Screw.h:192
double thickness
Definition: Screw.h:209
Mdouble get_WallInteractionRadius() const
const Vec3D & get_Position() const
Vec3D get_Velocity() const
Todo{Implement this function correctly}.
Definition: Screw.h:205
Mdouble Y
Definition: Vector.h:44
void set_zero()
Definition: Vector.h:55
double N
Definition: Screw.h:209
Screw()
Definition: Screw.h:45
Mdouble GetLength() const
Definition: Vector.h:248
double omega
Definition: Screw.h:209
double MaxR
Definition: Screw.h:209
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:40
Mdouble Z
Definition: Vector.h:44
const Mdouble sqr_pi
Definition: ExtendedMath.h:56
void print(std::ostream &os) const
outputs wall
Definition: Screw.h:199