MercuryDPM  Trunk
 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-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 
27 #include "BaseWall.h"
28 #include "DPMBase.h"
29 
37 {
38  handler_ = nullptr;
39  logger(DEBUG, "BaseWall::BaseWall() finished");
40 }
41 
51  : BaseInteractable(w)
52 {
53  //sets the current handler to that belonging to the existing wall, w
54  handler_ = w.handler_;
55  renderedWalls_.reserve(w.renderedWalls_.capacity());
57  for (auto* const r : w.renderedWalls_)
58  renderedWalls_.push_back(r->copy());
59  logger(DEBUG, "BaseWall::BaseWall(const BaseWall &p) finished");
60 }
61 
67 {
68  logger(DEBUG, "BaseWall::~BaseWall() finished");
69  for (auto* const r : renderedWalls_)
70  delete r;
71  renderedWalls_.clear();
72 }
73 
80 void BaseWall::read(std::istream& is)
81 {
83  unsigned size;
84  std::string type;
85  if (helpers::isNext(is,"vtkVisibility")) {
86  is >> vtkVisibility_;
87  }
88  if (helpers::isNext(is,"renderedWalls")) {
89  is >> size;
90  for (unsigned i = 0; i < size; i++)
91  {
92  is >> type;
93  BaseWall* wall = getHandler()->createObject(type);
94  wall->setHandler(getHandler());
95  wall->read(is);
96  renderedWalls_.push_back(wall);
97  renderedWalls_.back()->setId(renderedWalls_.size());
98  }
99  }
100 }
101 
102 void BaseWall::write(std::ostream& os) const
103 {
105  if (vtkVisibility_==false)
106  {
107  os << " vtkVisibility " << vtkVisibility_;
108  }
109  if (renderedWalls_.size()>0)
110  {
111  os << " renderedWalls " << renderedWalls_.size();
112  for (auto w : renderedWalls_)
113  {
114  os << " ";
115  w->write(os);
116  }
117  }
118 }
119 
128 {
129  handler_ = handler;
130  setSpecies(getHandler()->getDPMBase()->speciesHandler.getObject(getIndSpecies()));
131 }
132 
137 {
138  return handler_;
139 }
140 
144 void BaseWall::setIndSpecies(unsigned int indSpecies)
145 {
146  if (handler_ != nullptr)
147  {
148  setSpecies(getHandler()->getDPMBase()->speciesHandler.getObject(getIndSpecies()));
149  }
150  else
151  {
153  logger(ERROR, "setIndSpecies called on a particle with no particle handler.\n"
154  "Therefore I can't request the given species from the species handler.\n"
155  " PartID = %", getId());
156  }
157 }
158 
172 {
174  //Checks if the current wall currently belongs to a defined wallHandler...
175  if (getHandler() == nullptr)
176  {
177  //and if not:
178  //Creates a pointer to the handler to which the chosen species belongs
179  SpeciesHandler* sH = species->getHandler();
180  //Creates a pointer back to the DPMBase class
181  DPMBase* dB = sH->getDPMBase();
182  //If this is not a null pointer, assigns the current wall to the relevant wallHandler.
183  if (dB != nullptr)
184  setHandler(&dB->wallHandler);
185  }
186 }
187 
188 bool BaseWall::isFixed() const
189 {
190  return true;
191 }
192 
198 void BaseWall::setForceControl(Vec3D forceGoal, Vec3D gainFactor, Vec3D baseVelocity) {
199  setPrescribedVelocity([this, forceGoal, gainFactor, baseVelocity] (double time){
200  auto dForce = getForce()-forceGoal;
201  return baseVelocity + gainFactor.multiplyElementwise(dForce);
202  });
203 }
204 
205 // returns the point intersecting a wall (x-p).n=0 and a line x=p0+t(p1-p0)
206 bool BaseWall::getLinePlaneIntersect(Vec3D& intersect, const Vec3D& p0, const Vec3D& p1, const Vec3D& n, const Vec3D& p)
207 {
208  // t = (p-p0).n / (p1-p0).n
209  //first compute the denominator
210  Mdouble denominator = Vec3D::dot(p1 - p0, n);
211  if (fabs(denominator) >= 1e-10)
212  {
213  Mdouble t = Vec3D::dot(p - p0, n) / denominator;
214  if (t < 1 + 1e-12 && t > -1e-12)
215  intersect = p0 + t * (p1 - p0);
216  return true;
217  }
218  return false;
219 }
220 
221 //checks if point is in wall (if close to the wall, the point is assumed out of the wall)
222 bool BaseWall::isInsideWallVTK(const Vec3D& point, const Vec3D& normal, const Vec3D& position) const
223 {
224  return Vec3D::dot(position - point, normal) < -1e-12;
225 }
226 
233 void BaseWall::projectOntoWallVTK(Vec3D& point0, const Vec3D& point1, const Vec3D& normal, const Vec3D& position) const
234 {
235  Vec3D dPoint = point1 - point0;
236  point0 += Vec3D::dot(position - point0, normal) / Vec3D::dot(dPoint, normal) * dPoint;
237 }
238 
243 void BaseWall::intersectVTK(std::vector<Vec3D>& points, const Vec3D normal, const Vec3D position) const
244 {
245  // find first point in Wall
246  std::vector<Vec3D>::iterator firstIn = points.begin();
247  for (; firstIn != points.end(); firstIn++)
248  {
249  //stop if points[first] is in domain
250  if (isInsideWallVTK(*firstIn, normal, position))
251  {
252  break;
253  }
254  }
255 
256  //if all points are out of the wall
257  if (firstIn == points.end())
258  {
259  logger(DEBUG, "BaseWall::intersectVTK: all points out of wall");
260  return;
261  }
262 
263  // find first point out of the wall after firstIn
264  std::vector<Vec3D>::iterator firstOut = firstIn + 1;
265  for (; firstOut != points.end(); firstOut++)
266  {
267  if (!isInsideWallVTK(*firstOut, normal, position))
268  {
269  break;
270  }
271  }
272 
273  //if all points are in the wall
274  if (firstOut == points.end() && firstIn == points.begin())
275  {
276  logger(DEBUG, "BaseWall::intersectVTK: points completely in wall; removing points");
277  points.clear();
278  return;
279  }
280 
281  //if the sequence starts with a point out of the wall
282  //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
283  //In addition, we add the case iiioo and ioo
284  if (firstIn != points.begin() || !isInsideWallVTK(points.back(), normal, position))
285  {
286  // remove unnessesary points in the wall
287  // ooiiioo -> ooiioo, ooiii -> ooii, iiioo -> iioo
288  if (firstOut - firstIn > 2)
289  {
290  logger(DEBUG, "BaseWall::intersectVTK: remove unnessesary points in the wall");
291  //necessary reset of firstOut, as erase invalidates iterators after erase point
292  points.erase(firstIn + 1, firstOut - 1); //note: erase does not delete the last point
293  firstOut = firstIn + 2;
294  }
295 
296  // if there is only one point in the wall, make it two
297  // ooioo -> ooiioo, ooi -> ooii
298  if (firstOut == firstIn + 1)
299  {
300  logger(DEBUG, "BaseWall::intersectVTK: there is only one point in the wall, make it two");
301  //necessary reset of firstIn, firstOut, as insert invalidates iterators
302  unsigned in = firstIn - points.begin();
303  points.insert(firstIn + 1, *firstIn);
304  firstIn = points.begin() + in;//necessary, unless capacity is set right
305  firstOut = firstIn + 2;
306  }
307 
308  // three cases remain: ooiioo, ooii, iioo
309 
310  //move both points onto the surface of the wall
311  if (firstIn != points.begin())
312  {
313  logger(DEBUG, "BaseWall::intersectVTK: move first point onto the surface of the wall");
314  projectOntoWallVTK(*firstIn, *(firstIn - 1), normal, position);
315  }
316  else
317  {
318  logger(DEBUG,
319  "BaseWall::intersectVTK: move first point (at the beginning of the list) onto the surface of the wall");
320  projectOntoWallVTK(points.front(), points.back(), normal, position);
321  }
322 
323  if (firstOut != points.end())
324  {
325  logger(DEBUG, "BaseWall::intersectVTK: move second point onto the surface of the wall");
326  projectOntoWallVTK(*(firstOut - 1), *firstOut, normal, position);
327  }
328  else
329  {
330  logger(DEBUG,
331  "BaseWall::intersectVTK: move second point (at the end of the list) onto the surface of the wall");
332  projectOntoWallVTK(points.back(), points.front(), normal, position);
333  }
334  //if sequence starts and ends with a point in the wall: iiiooiii
335  }
336  else
337  {
338  logger(DEBUG, "BaseWall::intersectVTK: sequence starts and ends with a point in the wall");
339 
340  // find first point in wall after firstOut
341  for (firstIn = firstOut + 1; firstIn != points.end(); firstIn++)
342  {
343  if (isInsideWallVTK(*firstIn, normal, position))
344  {
345  break;
346  }
347  }
348 
349  // remove unnessesary points in the wall
350  // iiiooiii -> iooi
351  points.erase(firstIn + 1, points.end());
352  points.erase(points.begin(),
353  firstOut - 1); //note: erase does not delete the last point //note iterators are invalid now
354 
355  //move both points onto the surface of the wall: iooi
356  projectOntoWallVTK(points.front(), *(points.begin() + 1), normal, position);
357  projectOntoWallVTK(points.back(), *(points.end() - 2), normal, position);
358  }
359 }
360 
369 BaseWall::getInteractionWith(BaseParticle* p, unsigned timeStamp, InteractionHandler* interactionHandler)
370 {
371  Mdouble distance;
372  Vec3D normal;
373  Mdouble overlap;
374 
375  if (getDistanceNormalOverlap(*p, distance, normal, overlap))
376  {
377  // look for an existing interaction, or create a new one
378  BaseInteraction *c = nullptr;
379  // This if-statement deals with groups of walls. If a particle has multiple contacts with a group of walls, and if the contact areas of these contacts overlap, then we keep only the biggest of the overlapping contacts.
380  if (getGroupId() > 0 && p->getInteractions().size() > 0) {
381  // if there is a contact with a group of walls, and if p had at least one previously detected contact (in the last timestep or the current)
382  for (const auto i : p->getInteractions()) {
383  if (i->getI() == (BaseInteractable *) this) {
384  // if there is an existing interaction with this wall, keep it
385  i->setTimeStamp(timeStamp);
386  c = i;
387  break;
388  }
389  if (i->getI()->getGroupId() == getGroupId()) {
390  // update contact, otherwise the distance comparison iis not correct
391  // (note this is costly and we should replace this with a quicker algorithm if possible)
392  if (i->getTimeStamp() < timeStamp) {
393  double distance, overlap;
394  Vec3D normal;
395  static_cast<BaseWall*>(i->getI())->getDistanceNormalOverlap(*p, distance, normal, overlap);
396  i->setNormal(-normal);
397  i->setDistance(distance);
398  i->setOverlap(overlap);
399  }
400  // if another interaction with a wall of the same group is found
401  double proj = Vec3D::dot(-normal, i->getNormal());
402  // if the two contacts share a contact area, keep only the contact with the minimum distance
403  if (distance >= i->getDistance()) {
404  // if that other contact is closer to the particle than this one
405  if (proj * distance > (1.0-1e-12) * i->getDistance()) {
406  //if one contact point is in the contact area of the other point
407  //(I take the vector a=radius*n, project it onto the other normal ni: b=(a.ni)ni, and check that |a|>(r-delta_i), which is equivalent to checking whether position+a is a distance less than the contact radius from the normal vector ni )
408  //logger(INFO,"Ignoring contact with % because contact with % is closer",getId(),i->getI()->getId());
409  return nullptr;
410  }
411  //else, continue to compute this contact
412  } else {
413  // if this contact is closer to the particle than the other one
414  if (proj * i->getDistance() >= (1.0-1e-12) * distance) {
415  //if the other contact point is in the contact area of this point, replace the other contact with this one
416  i->setI(this);
417  c = i;
418  // if the contact force has already been computed (with the other wall), undo the force/torque computation
419  if (i->getTimeStamp() == timeStamp) {
420  p->addForce(-i->getForce());
421  this->addForce(i->getForce());
422  if (getHandler()->getDPMBase()->getRotation()) {
423  p->addTorque(-i->getTorque() + Vec3D::cross(p->getPosition() - i->getContactPoint(), i->getForce()));
424  this->addTorque(i->getTorque() - Vec3D::cross(this->getPosition() - i->getContactPoint(), i->getForce()));
425  }
426  }
427  i->setTimeStamp(timeStamp);
428  break;
429  }
430  }
431  }
432  }
433  }
434 
435  if (c == nullptr) {
436  // look for an existing interaction, or create a new one
437  c = interactionHandler->getInteraction(p, this, timeStamp);
438  }
439 
440  c->setNormal(-normal);
441  c->setDistance(distance);
442  c->setOverlap(overlap);
443  if (p->isSphericalParticle())
444  {
446  c->setContactPoint(p->getPosition() - (p->getRadius() - 0.5 * c->getOverlap()) * c->getNormal());
447  }
448  else
449  {
450  Vec3D normalBodyFixed = normal;
451  p->getOrientation().rotateBack(normalBodyFixed);
452  auto furthestPoint = getFurthestPointSuperQuadric(normalBodyFixed, p->getAxes(),
453  p->getExponentEps1(), p->getExponentEps2());
454  Vec3D overlapBody = overlap * normalBodyFixed;
455  Vec3D contactPoint = furthestPoint - overlapBody / 2;
456  p->getOrientation().rotate(contactPoint);
457  contactPoint += p->getPosition();
458  c->setContactPoint(contactPoint);
459  }
460  logger(DEBUG, "Particle contact with wall at %", c->getContactPoint());
461  return c;
462  }
463  return nullptr;
464 }
465 
467 {
468  logger(WARN, "Walls % of type % have no vtk writer defined", getIndex(), getName());
469 }
470 
471 void BaseWall::addToVTK(const std::vector<Vec3D>& points, VTKContainer& vtk)
472 {
473  if (!points.empty())
474  {
475  //all all values in myPoints to points
476  vtk.points.insert(vtk.points.end(), points.begin(), points.end());
477 
478  // create one cell object containing all indices of the added points (created a triangle strip connecting these points)
479  std::vector<double> cell;
480  cell.reserve(vtk.points.size() + 1);
481  cell.push_back(vtk.points.size() - 1);
482  for (unsigned i = vtk.points.size() - points.size(); i < vtk.points.size(); i++)
483  {
484  cell.push_back((double) i);
485  }
486 
487  //add this triangle strip to the vtk file
488  vtk.triangleStrips.push_back(cell);
489  }
490 }
491 
492 
495  InteractionHandler* interactionHandler)
496 {
497  logger(ERROR, "Generic wall-superquad interactions not implemented yet.");
498  return nullptr;
499 }
500 
504 {
506  Vec3D axis;
507  axis.X = Q.q1;
508  axis.Y = Q.q2;
509  axis.Z = Q.q3;
510  return axis;
511 }
512 
514 {
515  return vtkVisibility_;
516 }
517 
518 void BaseWall::setVTKVisibility(const bool vtkVisibility)
519 {
520  vtkVisibility_ = vtkVisibility;
521 }
522 
523 bool BaseWall::getDistanceNormalOverlap(const BaseParticle& P, Mdouble& distance, Vec3D& normal_return,
524  Mdouble& overlap) const
525 {
526  if (P.isSphericalParticle())
527  {
528  bool isInContact = getDistanceAndNormal(P, distance, normal_return);
529  overlap = P.getRadius() - distance;
530  return isInContact;
531  }
532  else
533  {
534  auto superQuadric = dynamic_cast<const SuperQuadricParticle*>(&P);
535  return getDistanceNormalOverlapSuperquadric(*superQuadric, distance, normal_return, overlap);
536  }
537 }
538 
539 bool
541  Mdouble& overlap) const
542 {
543  logger(ERROR, "Generic wall-superquadric interactions not implemented yet.");
544  return false;
545 }
546 
547 Vec3D BaseWall::getFurthestPointSuperQuadric(const Vec3D& normalBodyFixed, const Vec3D& axes, Mdouble eps1, Mdouble eps2) const
548 {
549  logger(ERROR, "Generic wall-superquadric interactions not implemented yet.");
550  return {};
551 }
552 
553 //todo how do i write a copy and add function?
555 {
556  renderedWalls_.push_back(w);
557 }
558 
560  while (!renderedWalls_.empty()) {
561  renderedWalls_.pop_back();
562  }
563 }
564 
566 {
567  return renderedWalls_[i];
568 }
569 
571 {
572  if (getVTKVisibility())
573  {
574  if (renderedWalls_.empty())
575  {
576  writeVTK(vtk);
577  }
578  else
579  {
580  const Mdouble time = getHandler()->getDPMBase()->getTime();
581  for (const auto& r: renderedWalls_)
582  {
583  r->applyPrescribedPosition(time);
584  r->applyPrescribedOrientation(time);
585  r->writeVTK(vtk);
586  }
587  }
588  }
589 }
590 
591 void BaseWall::setVelocityControl(Vec3D forceGoal, Vec3D gainFactor, Vec3D baseVelocity) {
592  setPrescribedVelocity([this, forceGoal, gainFactor, baseVelocity] (double time){
593  auto dForce = getForce()-forceGoal;
594  return baseVelocity + gainFactor.multiplyElementwise(dForce);
595  });
596 }
597 
598 void BaseWall::addParticlesAtWall(unsigned numElements)
599 {
600  auto& speciesHandler = getHandler()->getDPMBase()->speciesHandler;
601  logger.assert_always(speciesHandler.getSize()>0,"addParticlesAtWall: You need to define at least one species");
602 
603  Vec3D max = getHandler()->getDPMBase()->getMax();
604  Vec3D min = getHandler()->getDPMBase()->getMin();
605  double h = Vec3D::min(max-min)/numElements;
606  double r = 0.5*h;
607 
608  auto& particleHandler = getHandler()->getDPMBase()->particleHandler;
609  double numParticles0 = particleHandler.getSize();
611  p.setSpecies(speciesHandler.getObject(0));
612  Vec3D pos;
613  for (pos.X = min.X; pos.X <= max.X; pos.X += h)
614  for (pos.Y = min.Y; pos.Y <= max.Y; pos.Y += h)
615  for (pos.Z = min.Z; pos.Z <= max.Z; pos.Z += h)
616  {
617  Vec3D normal;
618  Mdouble distance;
619  p.setRadius(2.0*r);
620  p.setPosition(pos);
621  //if touching the wall
622  if (getDistanceAndNormal(p, distance, normal) && distance>=0)
623  {
624  p.setRadius(r);
625  p.setPosition(pos+(distance-r)*normal);
626  particleHandler.copyAndAddObject(p);
627  }
628  }
629  logger(INFO,"Inserted % particles that touch wall %", particleHandler.getNumberOfObjects()-numParticles0, getIndex());
630 }
void setPrescribedVelocity(const std::function< Vec3D(double)> &prescribedVelocity)
Allows the velocity of an infinite mass interactable to be prescribed.
Implementation of a 3D quaternion (by Vitaliy).
Definition: Quaternion.h:62
Container to store all ParticleSpecies.
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.h:125
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.h:118
const Vec3D getAxis() const
Definition: BaseWall.cc:503
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
virtual Vec3D getFurthestPointSuperQuadric(const Vec3D &normalBodyFixed, const Vec3D &axes, Mdouble eps1, Mdouble eps2) const
Definition: BaseWall.cc:547
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:72
void setNormal(Vec3D normal)
Sets the normal vector between the two interacting objects.
Mdouble X
the vector components
Definition: Vector.h:65
A basic particle.
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655
virtual bool isSphericalParticle() const
Definition: BaseParticle.h:642
void rotateBack(Vec3D &position) const
Applies the inverse rotation to a position.
Definition: Quaternion.cc:592
void intersectVTK(std::vector< Vec3D > &points, Vec3D normal, Vec3D position) const
Definition: BaseWall.cc:243
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:466
double Mdouble
Definition: GeneralDefine.h:34
virtual void setRadius(Mdouble radius)
Sets the particle's radius_ (and adjusts the mass_ accordingly, based on the particle's species) ...
void addForce(const Vec3D &addForce)
Adds an amount to the force on this BaseInteractable.
void renderWall(VTKContainer &vtk)
Definition: BaseWall.cc:570
Vec3D multiplyElementwise(const Vec3D &a) const
Definition: Vector.h:132
Vec3D getMin() const
Definition: DPMBase.h:623
const std::complex< Mdouble > i
Definition: ExtendedMath.h:50
virtual void setHandler(WallHandler *handler)
A function which sets the WallHandler for this BaseWall.
Definition: BaseWall.cc:127
virtual Mdouble getExponentEps1() const
Only ustilised in case of superquadric particles. Had to create a virtual function to allow function ...
bool isFixed() const override
Definition: BaseWall.cc:188
static void addToVTK(const std::vector< Vec3D > &points, VTKContainer &vtk)
Takes the points provided and adds a triangle strip connecting these points to the vtk container...
Definition: BaseWall.cc:471
virtual Vec3D getAxes() const
Only ustilised in case of superquadric particles. Had to create a virtual function to allow function ...
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
WallHandler * handler_
Definition: BaseWall.h:204
Mdouble q2
the second component of the quaternion q = (q0,q1,q2,q3)
Definition: Quaternion.h:77
virtual Mdouble getExponentEps2() const
Only ustilised in case of superquadric particles. Had to create a virtual function to allow function ...
void setSpecies(const ParticleSpecies *species)
const Vec3D & getContactPoint() const
Gets constant reference to contact point (vector).
void setVelocityControl(Vec3D forceGoal, Vec3D gainFactor, Vec3D baseVelocity)
Definition: BaseWall.cc:591
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:76
void rotate(Vec3D &position) const
Applies the rotation to a position.
Definition: Quaternion.cc:563
const Vec3D & getForce() const
Returns the force on this BaseInteractable.
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: BaseWall.cc:369
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 ...
const Vec3D & getNormal() const
Gets the normal vector between the two interacting objects.
SpeciesHandler * getHandler() const
Returns the pointer to the handler to which this species belongs.
Definition: BaseSpecies.cc:99
WallHandler * getHandler() const
A function which returns the WallHandler that handles this BaseWall.
Definition: BaseWall.cc:136
static BaseWall * createObject(const std::string &type)
Create a new wall, with the type given as a string (required for restarting).
Definition: WallHandler.cc:122
void setSpecies(const ParticleSpecies *species)
Sets the species of this BaseInteractable.
void write(std::ostream &os) const override
Write a BaseInteractable to an output stream.
virtual std::string getName() const =0
A purely virtual function.
static Vec3D min(const Vec3D &a, const Vec3D &b)
Calculates the pointwise minimum of two Vec3D.
Definition: Vector.cc:102
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...
BaseInteraction * getInteraction(BaseInteractable *P, BaseInteractable *I, unsigned timeStamp)
Returns the Interaction between the BaseInteractable's P and I.
Mdouble q3
the third component of the quaternion q = (q0,q1,q2,q3)
Definition: Quaternion.h:81
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created...
Definition: DPMBase.h:1329
std::vector< std::vector< double > > triangleStrips
Definition: BaseWall.h:39
Container to store Interaction objects.
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:613
bool getVTKVisibility() const
Definition: BaseWall.cc:513
bool isInsideWallVTK(const Vec3D &point, const Vec3D &normal, const Vec3D &position) const
Definition: BaseWall.cc:222
virtual bool getDistanceNormalOverlapSuperquadric(const SuperQuadricParticle &p, Mdouble &distance, Vec3D &normal_return, Mdouble &overlap) const
Definition: BaseWall.cc:540
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:163
Mdouble getRadius() const
Returns the particle's radius.
Definition: BaseParticle.h:345
BaseWall()
Default constructor.
Definition: BaseWall.cc:36
Basic class for walls.
Definition: BaseWall.h:47
Mdouble getOverlap() const
Returns a Mdouble with the current overlap between the two interacting objects.
void setVTKVisibility(bool vtkVisibility)
Definition: BaseWall.cc:518
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1319
BaseWall * getRenderedWall(size_t i) const
Definition: BaseWall.cc:565
void read(std::istream &is) override
Function that reads a BaseWall from an input stream, usually a restart file.
Definition: BaseWall.cc:80
Vec3D getMax() const
Definition: DPMBase.h:629
~BaseWall() override
Default destructor.
Definition: BaseWall.cc:66
Mdouble Y
Definition: Vector.h:65
virtual BaseInteraction * getInteractionWithSuperQuad(SuperQuadricParticle *p, unsigned timeStamp, InteractionHandler *interactionHandler)
Definition: BaseWall.cc:494
unsigned getGroupId() const
Definition: BaseObject.h:137
std::vector< BaseWall * > renderedWalls_
Definition: BaseWall.h:211
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1339
Container to store all BaseWall.
Definition: WallHandler.h:42
bool vtkVisibility_
Definition: BaseWall.h:206
bool isNext(std::istream &is, const std::string name)
reads next value in stream as a string and compares it with name.
Definition: Helpers.cc:944
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
std::vector< Vec3D > points
Definition: BaseWall.h:38
void setForceControl(Vec3D forceGoal, Vec3D gainFactor, Vec3D baseVelocity={0, 0, 0})
Slowly adjusts the force on a wall towards a specified goal, by adjusting (prescribing) the velocity ...
Definition: BaseWall.cc:198
void setIndSpecies(unsigned int indSpecies) override
Define the species of this wall using the index of the species in the SpeciesHandler in this DPMBase...
Definition: BaseWall.cc:144
const std::vector< BaseInteraction * > & getInteractions() const
Returns a list of interactions which belong to this interactable.
Defines the basic properties that a interactable object can have.
void addTorque(const Vec3D &addTorque)
Adds an amount to the torque on this BaseInteractable.
void removeRenderedWalls()
Definition: BaseWall.cc:559
unsigned int getIndSpecies() const
Returns the index of the species associated with the interactable object.
Definition: Vector.h:49
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:725
const Quaternion & getOrientation() const
Returns the orientation of this BaseInteractable.
Mdouble Z
Definition: Vector.h:65
void projectOntoWallVTK(Vec3D &point0, const Vec3D &point1, const Vec3D &normal, const Vec3D &position) const
Definition: BaseWall.cc:233
bool getLinePlaneIntersect(Vec3D &intersect, const Vec3D &p0, const Vec3D &p1, const Vec3D &n, const Vec3D &p)
Definition: BaseWall.cc:206
bool getRotation() const
Indicates whether particle rotation is enabled or disabled.
Definition: DPMBase.h:545
void read(std::istream &is) override
Reads a BaseInteractable from an input stream.
Mdouble getTime() const
Returns the current simulation time.
Definition: DPMBase.cc:797
virtual bool getDistanceNormalOverlap(const BaseParticle &P, Mdouble &distance, Vec3D &normal_return, Mdouble &overlap) const
Definition: BaseWall.cc:523
Mdouble q1
the first component of the quaternion q = (q0,q1,q2,q3)
Definition: Quaternion.h:73
void addParticlesAtWall(unsigned numElements=50)
Definition: BaseWall.cc:598
virtual void setIndSpecies(unsigned int indSpecies)
Sets the index of the Species of this BaseInteractable.
void setSpecies(const ParticleSpecies *species)
Defines the species of the current wall.
Definition: BaseWall.cc:171
void addRenderedWall(BaseWall *w)
Definition: BaseWall.cc:554