MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VChute.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2020, 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 "VChute.h"
27 #include "InteractionHandler.h"
28 #include "Particles/BaseParticle.h"
29 #include "Math/ExtendedMath.h"
30 
31 /* A finite-length V-chute. */
32 
34 {
35  l_ = 1.0;
36  w_ = 1.0;
37  alpha_ = 20.0 / 180.0 * constants::pi;
38 }
39 
40 VChute::VChute(const VChute& other) : BaseWall(other)
41 {
42  l_ = other.l_;
43  w_ = other.w_;
44  alpha_ = other.alpha_;
45 }
46 
47 VChute::VChute(Mdouble length, Mdouble width, Mdouble alpha)
48 {
49  l_ = length;
50  w_ = width;
51  alpha_ = alpha;
52 }
53 
54 VChute::~VChute() = default;
55 
56 void VChute::set(Mdouble length, Mdouble width, Mdouble alpha)
57 {
58  l_ = length;
59  w_ = width;
60  alpha_ = alpha;
61 }
62 
64 {
65  return new VChute(*this);
66 }
67 
68 bool VChute::getDistanceAndNormal(const BaseParticle& p, Mdouble& distance, Vec3D& normal_return) const
69 {
70  /* define shortcuts */
71  const Mdouble x0 = p.getPosition().X;
72  const Mdouble y0 = p.getPosition().Y;
73  const Mdouble z0 = p.getPosition().Z;
74  const Mdouble ra = p.getWallInteractionRadius(this); // note, not getRadius()
75 
76  /* Has the particle flown off the ends of the chute? */
77  if (x0 < -ra || x0 > l_ + ra)
78  return false;
79 
80  /* Don't bother bounding in the y, z directions. The wall is linear, so
81  * calculating collisions isn't that expensive anyway. */
82  /*
83  if (fabs(y0) > w_ + ra
84  || z0 < -ra || z0 > tan(alpha_)*(w_ + ra) + ra ) {
85  return false;
86  }
87  */
88 
89  /* Get the distance and normal. */
90  // Newton is unnecessary, because linear problem.
91  // The special case y0==0 is problematic because it means double-contact, but
92  // let's just hope it doesn't come up. (TODO)
93  Mdouble q;
94  Mdouble distanceSquared;
95  if (y0 > 0)
96  {
97  q = y0 * pow(cos(alpha_), 2) + z0 * tan(alpha_);
98  distanceSquared = pow(
99  y0 * (pow(cos(alpha_), 2) - 1) + z0 * sin(alpha_) * cos(alpha_), 2)
100  + pow(
101  y0 * sin(alpha_) * cos(alpha_) + z0 * (pow(sin(alpha_), 2) - 1), 2);
102  }
103  else if (y0 < 0)
104  {
105  q = y0 * pow(cos(alpha_), 2) - z0 * tan(alpha_);
106  distanceSquared = pow(
107  y0 * (pow(cos(alpha_), 2) - 1) - z0 * sin(alpha_) * cos(alpha_), 2)
108  + pow(
109  -y0 * sin(alpha_) * cos(alpha_) + z0 * (pow(sin(alpha_), 2) - 1), 2);
110  }
111  else
112  {
113  /* The case y=0 requires special handling... */
114 
115  /* In the past, this case simply triggered an error and died. */
116  // return false;
117 
118  /* If the particle has y=0 then it is in contact with both sides of the
119  * V-chute; both sides will exert a force on the particle
120  * simultaneously. This is difficult to handle. I shall assume that the
121  * resultant force is exactly upwards, as though the particle was in
122  * contact with a flat plane (z=0).
123  * TODO try to make this more realistic
124  */
125  std::cerr << "y0 == 0, dangerous" << std::endl;
126  q = 0;
127  distanceSquared = pow(z0, 2);
128  }
129 
130  //If distance is too large there is no contact
131  if (distanceSquared >= pow(p.getWallInteractionRadius(this), 2))
132  {
133  return false;
134  }
135 
136  Vec3D ContactPoint;
137  distance = sqrt(distanceSquared);
138  ContactPoint.X = x0;
139  ContactPoint.Y = q;
140  ContactPoint.Z = fabs(q) * tan(alpha_);
141  normal_return = ContactPoint - p.getPosition();
142  normal_return /= normal_return.getLength();
143  return true;
144 
145 }
146 
148 VChute::getInteractionWith(BaseParticle* p, unsigned timeStamp, InteractionHandler* interactionHandler)
149 {
150  Mdouble distance;
151  Vec3D normal;
152  if (getDistanceAndNormal(*p, distance, normal))
153  {
154  BaseInteraction* c = interactionHandler->getInteraction(p, this, timeStamp);
155  c->setNormal(-normal);
156  c->setDistance(distance);
157  c->setOverlap(p->getRadius() - distance);
158  c->setContactPoint(p->getPosition() - (p->getRadius() - 0.5 * c->getOverlap()) * c->getNormal());
160  return c;
161  }
162  else
163  return nullptr;
164 }
165 
169 void VChute::read(std::istream& is)
170 {
171  BaseWall::read(is);
172  std::string dummy;
173  is >> dummy >> l_
174  >> dummy >> w_
175  >> dummy >> alpha_;
176 }
177 
181 void VChute::write(std::ostream& os) const
182 {
183  BaseWall::write(os);
184  os << " Length " << l_
185  << " Width " << w_
186  << " alpha " << alpha_;
187 }
188 
192 std::string VChute::getName() const
193 {
194  return "VChute";
195 }
BaseInteraction * getInteractionWith(BaseParticle *p, unsigned timeStamp, InteractionHandler *interactionHandler) override
Returns the interaction between this wall and a given particle, nullptr if there is no interaction...
Definition: VChute.cc:148
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
void setNormal(Vec3D normal)
Sets the normal vector between the two interacting objects.
Mdouble X
the vector components
Definition: Vector.h:65
void setOverlap(Mdouble overlap)
Set the overlap between the two interacting object.
double Mdouble
Definition: GeneralDefine.h:34
void set(Mdouble length, Mdouble width, Mdouble alpha)
Definition: VChute.cc:56
std::string getName() const override
Definition: VChute.cc:192
void setContactPoint(Vec3D contactPoint)
Set the location of the contact point between the two interacting objects.
void write(std::ostream &os) const override
Function that writes a BaseWall to an output stream, usually a restart file.
Definition: BaseWall.cc:102
void setDistance(Mdouble distance)
Sets the interaction distance between the two interacting objects.
Stores information about interactions between two interactable objects; often particles but could be ...
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:331
const Vec3D & getNormal() const
Gets the normal vector between the two interacting objects.
Mdouble l_
Definition: VChute.h:62
Mdouble cos(Mdouble x)
Definition: ExtendedMath.cc:64
Definition: VChute.h:34
Mdouble getWallInteractionRadius(const BaseWall *wall) const
returns the radius plus the interactionDistance
Definition: BaseParticle.h:383
Mdouble sin(Mdouble x)
Definition: ExtendedMath.cc:44
const Mdouble pi
Definition: ExtendedMath.h:45
BaseInteraction * getInteraction(BaseInteractable *P, BaseInteractable *I, unsigned timeStamp)
Returns the Interaction between the BaseInteractable's P and I.
T tan(T x)
Definition: ExtendedMath.h:176
Container to store Interaction objects.
Mdouble alpha_
Definition: VChute.h:64
Mdouble getRadius() const
Returns the particle's radius.
Definition: BaseParticle.h:345
Basic class for walls.
Definition: BaseWall.h:47
Mdouble getOverlap() const
Returns a Mdouble with the current overlap between the two interacting objects.
VChute * copy() const override
Pure virtual function that can be overwritten in inherited classes in order to copy a BaseWall...
Definition: VChute.cc:63
VChute()
Definition: VChute.cc:33
void read(std::istream &is) override
Function that reads a BaseWall from an input stream, usually a restart file.
Definition: BaseWall.cc:80
void read(std::istream &is) override
Definition: VChute.cc:169
Mdouble Y
Definition: Vector.h:65
Mdouble w_
Definition: VChute.h:63
bool getDistanceAndNormal(const BaseParticle &p, Mdouble &distance, Vec3D &normal_return) const override
Pure virtual function that computes the distance of a BaseParticle to this wall and returns the norma...
Definition: VChute.cc:68
Definition: Vector.h:49
~VChute() override
Mdouble Z
Definition: Vector.h:65
void write(std::ostream &os) const override
Definition: VChute.cc:181