MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Coil.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 "Coil.h"
27 #include "InteractionHandler.h"
28 #include "Particles/BaseParticle.h"
29 
36 {
37  start_.setZero();
38  l_ = 1.0;
39  r_ = 1.0;
40  n_ = 1.0;
41  omega_ = 1.0;
42  offset_ = 0.0;
43  thickness_ = 0.0;
44  logger(DEBUG, "Coil() constructor finished");
45 }
46 
50 Coil::Coil(const Coil& other) : BaseWall(other)
51 {
52  start_ = other.start_;
53  l_ = other.l_;
54  r_ = other.r_;
55  n_ = other.n_;
56  omega_ = other.omega_;
57  offset_ = other.offset_;
58  thickness_ = other.thickness_;
59  logger(DEBUG, "Coil(const Coil&) copy constructor finished");
60 }
61 
72 Coil::Coil(Vec3D start, Mdouble l, Mdouble r, Mdouble n, Mdouble omega, Mdouble thickness)
73 {
74  start_ = start;
75  l_ = l;
76  r_ = r;
77  n_ = n;
78  omega_ = omega;
79  thickness_ = thickness;
80  offset_ = 0.0;
81  logger(DEBUG, "Coil(params) constructor with parameters finished.");
82 }
83 
85 {
86  logger(DEBUG, "~Coil() destructor finished.");
87 }
88 
101 void Coil::set(Vec3D start, Mdouble length, Mdouble radius, Mdouble numberOfRevelations, Mdouble omega, Mdouble thickness)
102 {
103  start_ = start;
104  l_ = length;
105  r_ = radius;
106  n_ = numberOfRevelations;
107  omega_ = omega;
108  thickness_ = thickness;
109  offset_ = 0.0;
110 }
111 
115 Coil* Coil::copy() const
116 {
117  return new Coil(*this);
118 }
119 
131 bool Coil::getDistanceAndNormal(const BaseParticle& p, Mdouble& distance, Vec3D& normal_return) const
132 {
133  Mdouble Rsqr = pow(p.getPosition().X - start_.X, 2) + pow(p.getPosition().Y - start_.Y, 2);
135  {
136  //std::cout<<"Particle is out of first bound checking"<<std::endl;
137  //std::cout<<"Rule 1: "<<pow(r-P.getRadius()-thickness_,2)<<"<"<<Rsqr<<"<"<<pow(r+P.getRadius()+thickness_,2)<<std::endl;
138  //std::cout<<"Rule 2: "<<Start.Z-P.getRadius()-thickness_<<"<"<<P.getPosition().Z<<"<"<<L+Start.Z+P.getRadius()+thickness_<<std::endl;
139  return false;
140  }
141  Mdouble R = sqrt(Rsqr);
142  Mdouble alpha = atan2(p.getPosition().Y - start_.Y, p.getPosition().X - start_.X);
143  Mdouble dz = p.getPosition().Z - start_.Z;
144 
145  //To find the contact point we have to minimize (with respect to q)
146  //Distance^2=(x-x0-r*cos(2*Pi*(offset+N*q)))^2+(y-y0-r*sin(2*Pi*(offset+N*q)))^2+(z-z0-q*L)^2
147  //Using polar coordinated (i.e. x-x0=R*cos(alpha), y-y0=R*sin(alpha) and dz=z-z0)
148  //Distance^2=R^2+r^2-2*R*r*cos(alpha-2*Pi*(offset+N*q))+(dz-q*L)^2
149 
150  //So we have to minimize:
151  //Distance^2=R^2+r^2-2*R*r*cos(alpha-2*Pi*(offset+N*q))+(dz-q*L)^2
152  //For this we use the Euler algoritm
153 
154  Mdouble q; //Current guess
155  Mdouble dd; //Derivative at current guess
156  Mdouble ddd; //Second derivative at current guess
157  Mdouble q0 = dz / l_; //Minimum of the parabolic part
158 
159  //The initial guess will be in the maximum of the cos closest to the minimum of the parabolic part
160  //Minima of the cos are at
161  //alpha-2*Pi*(offset+N*q)=2*k*Pi (k=integer)
162  //q=alpha/(2*Pi*N)-k/N-offset/N (k=integer)
163 
164  Mdouble k = round(alpha / 2.0 / constants::pi - (offset_ + n_ * q0));
165  q = alpha / (2 * constants::pi * n_) - k / n_ - offset_ / n_;
166 
167  //Now apply Newton's method
168  do
169  {
170  dd = -4.0 * R * r_ * constants::pi * n_ * sin(alpha - 2.0 * constants::pi * (n_ * q + offset_)) - 2.0 * l_ * (dz - q * l_);
171  ddd = 8.0 * R * r_ * constants::sqr_pi * n_ * n_ * cos(alpha - 2.0 * constants::pi * (n_ * q + offset_)) + 2.0 * l_ * l_;
172  q -= dd / ddd;
173  } while (fabs(dd / ddd) > 1e-14);
174 
175  //Check if the location is actually on the coil, otherwise a point collision with the end of the coil calculated
176  if (q < 0) //Left boundary of the coil
177  {
178  q = 0;
179  }
180  else if (q > 1) //right boundary of the coil
181  {
182  q = 1;
183  }
184 
185  Mdouble distanceSquared = R * R + r_ * r_ - 2 * R * r_ * cos(alpha - 2 * constants::pi * (offset_ + n_ * q)) + pow(dz - q * l_, 2);
186  //If distance is too large there is no contact
187  if (distanceSquared >= (p.getWallInteractionRadius() + thickness_) * (p.getWallInteractionRadius() + thickness_))
188  {
189  //std::cout<<"Particle is out of second bound checking, distance^2="<<distance<<" max="<<(P.getRadius()+thickness_)*(P.getRadius()+thickness_)<<std::endl;
190  return false;
191  }
192 
193  Vec3D ContactPoint;
194  distance = sqrt(distanceSquared) - thickness_;
195  ContactPoint.X = start_.X + r_ * cos(2.0 * constants::pi * (offset_ + n_ * q));
196  ContactPoint.Y = start_.Y + r_ * sin(2.0 * constants::pi * (offset_ + n_ * q));
197  ContactPoint.Z = start_.Z + q * l_;
198  normal_return = ContactPoint - p.getPosition();
199  normal_return /= normal_return.getLength();
200  return true;
201 }
202 
207 {
208  offset_ += omega_ * dt;
209 }
210 
214 void Coil::read(std::istream& is)
215 {
216  BaseWall::read(is);
217  std::string dummy;
218  is >> dummy >> start_
219  >> dummy >> l_
220  >> dummy >> r_
221  >> dummy >> n_
222  >> dummy >> omega_
223  >> dummy >> thickness_
224  >> dummy >> offset_;
225 }
226 
230 void Coil::oldRead(std::istream& is)
231 {
232  std::string dummy;
233  is >> dummy >> start_
234  >> dummy >> l_
235  >> dummy >> r_ >> dummy >> n_
236  >> dummy >> omega_
237  >> dummy >> offset_;
238 }
239 
243 void Coil::write(std::ostream& os) const
244  {
245  BaseWall::write(os);
246  os << " Start " << start_
247  << " Length " << l_
248  << " Radius " << r_
249  << " Revolutions " << n_
250  << " Omega " << omega_
251  << " Thickness " << thickness_
252  << " Offset " << offset_;
253 }
254 
258 std::string Coil::getName() const
259 {
260  return "Coil";
261 }
Vec3D start_
The centre of the lower end of the Coil.
Definition: Coil.h:110
Mdouble X
the vector components
Definition: Vector.h:52
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
void setZero()
Sets all elements to zero.
Definition: Vector.cc:52
void set(Vec3D Start, Mdouble length, Mdouble radius, Mdouble numberOfRevelations, Mdouble omega, Mdouble thickness)
Set all parameters of this Coil.
Definition: Coil.cc:101
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
~Coil()
Default destructor.
Definition: Coil.cc:84
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:414
Mdouble getWallInteractionRadius() const
Returns the interaction radius for interaction with walls. See also BaseParticle::getInteractionRadiu...
Mdouble cos(Mdouble x)
Definition: ExtendedMath.cc:60
Mdouble offset_
Definition: Coil.h:135
Mdouble sin(Mdouble x)
Definition: ExtendedMath.cc:42
void read(std::istream &is) override
Reads a Coil from an input stream, for example a restart file.
Definition: Coil.cc:214
const Mdouble pi
Definition: ExtendedMath.h:42
void write(std::ostream &os) const override
Writes a Coil to an output stream, for example a restart file.
Definition: Coil.cc:243
bool getDistanceAndNormal(const BaseParticle &P, Mdouble &distance, Vec3D &normal_return) const override
Compute the distance from the Coil for a given BaseParticle and return if there is a collision...
Definition: Coil.cc:131
Basic class for walls.
Definition: BaseWall.h:44
Mdouble Y
Definition: Vector.h:52
Mdouble l_
The length of the Coil.
Definition: Coil.h:115
Mdouble n_
Definition: Coil.h:125
void move_time(Mdouble dt)
Rotate the Coil for a period dt, so that the offset_ changes with omega_*dt.
Definition: Coil.cc:206
Mdouble r_
Definition: Coil.h:120
Coil * copy() const override
Copy this Coil and return a pointer to the copy, useful for polymorphism.
Definition: Coil.cc:115
Coil()
Default constructor, sets a coil with default parameters.
Definition: Coil.cc:35
Mdouble thickness_
Definition: Coil.h:140
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
MERCURY_DEPRECATED void oldRead(std::istream &is)
Reads an old-style Coil from an input stream, for example an old restart file.
Definition: Coil.cc:230
void write(std::ostream &os) const
Function that writes a BaseWall to an output stream, usually a restart file.
Definition: BaseWall.cc:68
Mdouble Z
Definition: Vector.h:52
This class defines a coil in the z-direction from a (constant) starting point, a (constant) length L...
Definition: Coil.h:40
const Mdouble sqr_pi
Definition: ExtendedMath.h:44
Mdouble omega_
Definition: Coil.h:130
void read(std::istream &is)
Function that reads a BaseWall from an input stream, usually a restart file.
Definition: BaseWall.cc:60
std::string getName() const override
Returns the name of the object, in this case the string "Coil".
Definition: Coil.cc:258