MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseWall.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 "BaseWall.h"
27 #include "DPMBase.h"
28 #include "WallHandler.h"
30 
32 {
33  handler_ = nullptr;
34  logger(DEBUG, "BaseWall::BaseWall() finished");
35 }
36 
42 {
43  handler_ = w.handler_;
44  logger(DEBUG, "BaseWall::BaseWall(const BaseWall &p) finished");
45 }
46 
48 {
49  logger(DEBUG, "BaseWall::~BaseWall() finished");
50 }
51 
53 {
54  logger(DEBUG, "BaseWall::clear(), this function shouldn't be called");
55 }
56 
60 void BaseWall::read(std::istream& is)
61 {
63 }
64 
68 void BaseWall::write(std::ostream& os) const
69 {
71 }
72 
77 {
78  handler_ = handler;
79  setSpecies(getHandler()->getDPMBase()->speciesHandler.getObject(getIndSpecies()));
80 }
81 
86 {
87  return handler_;
88 }
89 
93 void BaseWall::setIndSpecies(unsigned int indSpecies)
94 {
95  if (handler_ != nullptr)
96  {
97  setSpecies(getHandler()->getDPMBase()->speciesHandler.getObject(getIndSpecies()));
98  }
99  else
100  {
102  logger(ERROR, "setIndSpecies called on a particle with no particle handler.\n"
103  "Therefore I can't request the given species from the species handler.\n"
104  " PartID = %", getId());
105  }
106 }
107 
114 {
116 
117  //set pointer to the handler, which is needed to retrieve species information
118  if (getHandler() == nullptr)
119  {
120  SpeciesHandler* sH = species->getHandler();
121  DPMBase* dB = sH->getDPMBase();
122  if (dB != nullptr)
123  setHandler(&dB->wallHandler);
124  }
125 }
126 
127 // returns the point intersecting a wall (x-p).n=0 and a line x=p0+t(p1-p0)
128 bool BaseWall::getLinePlaneIntersect (Vec3D& intersect, const Vec3D& p0, const Vec3D& p1, const Vec3D& n, const Vec3D& p)
129 {
130  // t = (p-p0).n / (p1-p0).n
131  //first compute the denominator
132  Mdouble denominator = Vec3D::dot(p1-p0,n);
133  if (fabs(denominator)>=1e-10)
134  {
135  Mdouble t = Vec3D::dot(p-p0,n)/denominator;
136  if (t<1+1e-12&&t>-1e-12)
137  intersect = p0 + t * (p1-p0);
138  return true;
139  }
140  return false;
141 }
142 
143 //checks if point is in wall (if close to the wall, the point is assumed out of the wall)
144 bool BaseWall::isInsideWallVTK (const Vec3D& point, const Vec3D& normal, const Vec3D& position) const {
145  return Vec3D::dot(position-point,normal)<-1e-12;
146 }
147 
154 void BaseWall::projectOntoWallVTK (Vec3D& point0, const Vec3D& point1, const Vec3D& normal, const Vec3D& position) const {
155  Vec3D dPoint = point1-point0;
156  point0 += Vec3D::dot(position-point0,normal)/Vec3D::dot(dPoint,normal)*dPoint;
157 }
158 
163 void BaseWall::intersectVTK(std::vector<Vec3D> &points, const Vec3D normal, const Vec3D position) const
164 {
165  // find first point in Wall
166  std::vector<Vec3D>::iterator firstIn=points.begin();
167  for (;firstIn!=points.end(); firstIn++) {
168  //stop if points[first] is in domain
169  if (isInsideWallVTK(*firstIn,normal,position)) {
170  break;
171  }
172  }
173 
174  //if all points are out of the wall
175  if (firstIn==points.end()) {
176  logger(DEBUG, "BaseWall::intersectVTK: all points out of wall");
177  return;
178  }
179 
180  // find first point out of the wall after firstIn
181  std::vector<Vec3D>::iterator firstOut=firstIn+1;
182  for (;firstOut!=points.end(); firstOut++) {
183  if (!isInsideWallVTK(*firstOut,normal,position)) {
184  break;
185  }
186  }
187 
188  //if all points are in the wall
189  if (firstOut==points.end()&&firstIn==points.begin()) {
190  logger(DEBUG, "BaseWall::intersectVTK: points completely in wall; removing points");
191  points.clear();
192  return;
193  }
194 
195  //if the sequence starts with a point out of the wall
196  //Several cases have to be distinguished, multiple points in the wall the last point in or out of the wall: ooiiioo, ooioo, ooiii, or ooi
197  //In addition, we add the case iiioo and ioo
198  if (firstIn!=points.begin() || !isInsideWallVTK(points.back(),normal,position)) {
199  // remove unnessesary points in the wall
200  // ooiiioo -> ooiioo, ooiii -> ooii, iiioo -> iioo
201  if (firstOut-firstIn>2) {
202  logger(DEBUG, "BaseWall::intersectVTK: remove unnessesary points in the wall");
203  //necessary reset of firstOut, as erase invalidates iterators after erase point
204  points.erase(firstIn+1,firstOut-1); //note: erase does not delete the last point
205  firstOut = firstIn+2;
206  }
207 
208  // if there is only one point in the wall, make it two
209  // ooioo -> ooiioo, ooi -> ooii
210  if (firstOut==firstIn+1) {
211  logger(DEBUG, "BaseWall::intersectVTK: there is only one point in the wall, make it two");
212  //necessary reset of firstIn, firstOut, as insert invalidates iterators
213  unsigned in = firstIn-points.begin();
214  points.insert(firstIn+1,*firstIn);
215  firstIn = points.begin()+in;//necessary, unless capacity is set right
216  firstOut = firstIn+2;
217  }
218 
219  // three cases remain: ooiioo, ooii, iioo
220 
221  //move both points onto the surface of the wall
222  if (firstIn!=points.begin()) {
223  logger(DEBUG, "BaseWall::intersectVTK: move first point onto the surface of the wall");
224  projectOntoWallVTK(*firstIn, *(firstIn-1), normal, position);
225  } else {
226  logger(DEBUG, "BaseWall::intersectVTK: move first point (at the beginning of the list) onto the surface of the wall");
227  projectOntoWallVTK(points.front(), points.back(), normal, position);
228  }
229 
230  if (firstOut!=points.end()) {
231  logger(DEBUG, "BaseWall::intersectVTK: move second point onto the surface of the wall");
232  projectOntoWallVTK(*(firstOut-1), *firstOut, normal, position);
233  } else {
234  logger(DEBUG, "BaseWall::intersectVTK: move second point (at the end of the list) onto the surface of the wall");
235  projectOntoWallVTK(points.back(), points.front(), normal, position);
236  }
237  //if sequence starts and ends with a point in the wall: iiiooiii
238  } else {
239  logger(DEBUG, "BaseWall::intersectVTK: sequence starts and ends with a point in the wall");
240 
241  // find first point in wall after firstOut
242  for (firstIn=firstOut+1;firstIn!=points.end(); firstIn++) {
243  if (isInsideWallVTK(*firstIn,normal,position)) {
244  break;
245  }
246  }
247 
248  // remove unnessesary points in the wall
249  // iiiooiii -> iooi
250  points.erase(firstIn+1,points.end());
251  points.erase(points.begin(),firstOut-1); //note: erase does not delete the last point //note iterators are invalid now
252 
253  //move both points onto the surface of the wall: iooi
254  projectOntoWallVTK(points.front(), *(points.begin()+1), normal, position);
255  projectOntoWallVTK(points.back(), *(points.end()-2), normal, position);
256  }
257 }
258 
266 std::vector<BaseInteraction*> BaseWall::getInteractionWith(BaseParticle* p, Mdouble timeStamp, InteractionHandler* interactionHandler)
267 {
268  Mdouble distance;
269  Vec3D normal;
270  std::vector<BaseInteraction*> interactions;
271  if (getDistanceAndNormal(*p,distance,normal))
272  {
273  BaseInteraction* c = interactionHandler->getInteraction(p, this, timeStamp);
274  c->setNormal(-normal);
275  c->setDistance(distance);
276  c->setOverlap(p->getRadius() - distance);
278  c->setContactPoint(p->getPosition()-(p->getRadius() - 0.5 * c->getOverlap()) * c->getNormal());
279  interactions.push_back(c);
280  }
281  return interactions;
282 }
283 
285 {
286  logger(WARN,"Wall % (%) cannot has no vtk writer defined",getIndex(),getName());
287 }
288 
289 void BaseWall::addToVTK (const std::vector<Vec3D>& points, VTKContainer& vtk)
290 {
291  if (points.size()!=0) {
292  //all all values in myPoints to points
293  vtk.points.insert(vtk.points.end(), points.begin(), points.end());
294 
295  // create one cell object containing all indices of the added points (created a triangle strip connecting these points)
296  std::vector<double> cell;
297  cell.reserve(vtk.points.size()+1);
298  cell.push_back(vtk.points.size()-1);
299  for (unsigned i=vtk.points.size()-points.size(); i<vtk.points.size(); i++) {
300  cell.push_back(i);
301  }
302 
303  //add this triangle strip to the vtk file
304  vtk.triangleStrips.push_back(cell);
305  }
306 }
Container to store all ParticleSpecies.
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.cc:116
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:108
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:65
void setNormal(Vec3D normal)
Sets the normal vector between the two interacting objects.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void setOverlap(Mdouble overlap)
Set the overlap between the two interacting object.
virtual void writeVTK(VTKContainer &vtk) const
Definition: BaseWall.cc:284
virtual MERCURY_DEPRECATED void clear()
A function that removes all data from this BaseWall, so sets handler_ to nullptr. ...
Definition: BaseWall.cc:52
BaseInteraction * getInteraction(BaseInteractable *P, BaseInteractable *I, Mdouble timeStamp)
Returns the Interaction between the BaseInteractable's P and I.
void setIndSpecies(unsigned int indSpecies)
Define the species of this wall using the index of the species in the SpeciesHandler in this DPMBase...
Definition: BaseWall.cc:93
virtual void setHandler(WallHandler *handler)
A function which sets the WallHandler for this BaseWall.
Definition: BaseWall.cc:76
double Mdouble
static void addToVTK(const std::vector< Vec3D > &points, VTKContainer &vtk)
Definition: BaseWall.cc:289
void setContactPoint(Vec3D contactPoint)
Set the location of the contact point between the two interacting objects.
WallHandler * handler_
Definition: BaseWall.h:154
void intersectVTK(std::vector< Vec3D > &points, const Vec3D normal, const Vec3D position) const
Definition: BaseWall.cc:163
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:167
void setDistance(Mdouble distance)
Sets the interaction distance between the two interacting objects.
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Stores information about interactions between two interactable objects; often particles but could be ...
virtual std::vector< BaseInteraction * > getInteractionWith(BaseParticle *p, Mdouble timeStamp, InteractionHandler *interactionHandler)
Definition: BaseWall.cc:266
SpeciesHandler * getHandler() const
Returns the pointer to the handler to which this species belongs.
Definition: BaseSpecies.cc:74
WallHandler * getHandler() const
A function which returns the WallHandler that handles this BaseWall.
Definition: BaseWall.cc:85
void setSpecies(const ParticleSpecies *species)
Sets the species of this BaseInteractable.
virtual void read(std::istream &is)=0
Reads a BaseInteractable from an input stream.
virtual std::string getName() const =0
A purely virtual function.
virtual bool getDistanceAndNormal(const BaseParticle &P, Mdouble &distance, Vec3D &normal_return) const =0
Pure virtual function that computes the distance of a BaseParticle to this wall and returns the norma...
std::vector< std::vector< double > > triangleStrips
Definition: BaseWall.h:36
Container to store Interaction objects.
const Vec3D & getNormal() const
Gets the normal vector between the two interacting objects.
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:451
bool isInsideWallVTK(const Vec3D &point, const Vec3D &normal, const Vec3D &position) const
Definition: BaseWall.cc:144
Mdouble getRadius() const
Returns the particle's radius_.
BaseWall()
Default constructor. It makes an empty BaseWall.
Definition: BaseWall.cc:31
Basic class for walls.
Definition: BaseWall.h:44
Mdouble getOverlap() const
Returns a Mdouble with the current overlap between the two interacting objects.
virtual void setIndSpecies(unsigned int indSpecies)
Sets the index of the Species of this BaseInteractable.
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1006
Container to store all BaseWall.
Definition: WallHandler.h:42
std::vector< Vec3D > points
Definition: BaseWall.h:35
Defines the basic properties that a interactable object can have.
unsigned int getIndSpecies() const
Returns the index of the Species of this BaseInteractable.
virtual void write(std::ostream &os) const =0
Write a BaseInteractable to an output stream.
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:543
void write(std::ostream &os) const
Function that writes a BaseWall to an output stream, usually a restart file.
Definition: BaseWall.cc:68
void projectOntoWallVTK(Vec3D &point0, const Vec3D &point1, const Vec3D &normal, const Vec3D &position) const
Definition: BaseWall.cc:154
bool getLinePlaneIntersect(Vec3D &intersect, const Vec3D &p0, const Vec3D &p1, const Vec3D &n, const Vec3D &p)
Definition: BaseWall.cc:128
virtual ~BaseWall()
Default destructor.
Definition: BaseWall.cc:47
void read(std::istream &is)
Function that reads a BaseWall from an input stream, usually a restart file.
Definition: BaseWall.cc:60
void setSpecies(const ParticleSpecies *species)
Define the species of this wall.
Definition: BaseWall.cc:113