IntersectionOfWalls Class Reference

A IntersectionOfWalls is convex polygon defined as an intersection of InfiniteWall's. More...

#include <IntersectionOfWalls.h>

+ Inheritance diagram for IntersectionOfWalls:

Classes

struct  normalAndPosition
 

Public Member Functions

 IntersectionOfWalls ()
 Default constructor. More...
 
 IntersectionOfWalls (const IntersectionOfWalls &other)
 Copy constructor. More...
 
 IntersectionOfWalls (const std::vector< normalAndPosition > &walls, const ParticleSpecies *species)
 Constructor setting values. More...
 
 ~IntersectionOfWalls () override
 Destructor. More...
 
IntersectionOfWallsoperator= (const IntersectionOfWalls &other)
 
IntersectionOfWallscopy () const override
 Wall copy method. It calls the copy constructor of this Wall, useful for polymorphism. More...
 
void clear ()
 Removes all parts of the walls. More...
 
void setSpecies (const ParticleSpecies *species)
 sets species of subwalls as well More...
 
void setHandler (WallHandler *wallHandler) override
 A function which sets the WallHandler for this BaseWall. More...
 
unsigned int getNumberOfObjects ()
 Returns the number of objects. More...
 
void addObject (Vec3D normal, Vec3D point)
 Adds a wall to the set of infinite walls, given a normal vector pointing into the wall (i.e. out of the simulation domain), going through the point, so that normal*x=normal*point. More...
 
void addObject (Quaternion orientation, Vec3D position)
 
void add3PointObject (Vec3D PointA, Vec3D PointB, Vec3D PointC)
 
void setPointsAndLines (unsigned int n)
 
void addTetraSTL (Vec3D PointA, Vec3D PointB, Vec3D PointC, Vec3D WallNormal, Mdouble Thickness, int wallidentifier)
 constructs a tetrahedron for an STL file input More...
 
void addTetra (const Vec3D &PointA, const Vec3D &PointB, const Vec3D &PointC, Mdouble &Thickness)
 constructs a tetrahedron from 3 input coordinates More...
 
void addPlate (const Vec3D &PointA, const Vec3D &PointB, const Vec3D &PointC, const Vec3D &WallNormal, const Mdouble &Thickness, int wallidentifier)
 
MERCURYDPM_DEPRECATED void addObject (Vec3D normal, Mdouble position)
 Adds a wall to the set of finite walls, given an normal vector pointing into the wall (i.e. out of the flow domain), to give a plane defined by normal*x=position. More...
 
void createOpenPrism (std::vector< Vec3D > points, Vec3D prismAxis)
 Creates an open prism which is a polygon between the points, except the first and last point, and extends infinitely in the PrismAxis direction. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly. More...
 
void createPrism (std::vector< Vec3D > points, Vec3D prismAxis)
 Creates an open prism which is a polygon between the points and extends infinitely in the PrismAxis direction. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly. More...
 
void createOpenPrism (std::vector< Vec3D > points)
 Creates an open prism which is a polygon between the points, except the first and last point, and extends infinitely in the direction perpendicular to the first and second wall. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly. More...
 
void createPrism (std::vector< Vec3D > points)
 Creates an open prism which is a polygon between the points and extends infinitely in the direction perpendicular to the first and second wall. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly. More...
 
bool getDistanceAndNormal (const BaseParticle &p, Mdouble &distance, Vec3D &normal_return) const override
 Compute the distance from the wall for a given BaseParticle and return if there is a collision. If there is a collision, also return the normal vector. More...
 
bool getDistanceAndNormal (const Vec3D &position, Mdouble wallInteractionRadius, Mdouble &distance, Vec3D &normal_return) const
 Compute the distance from the wall for a given BaseParticle and return if there is an interaction. If there is an interaction, also return the normal vector. More...
 
void read (std::istream &is) override
 Move the IntersectionOfWalls to a new position, which is a Vec3D from the old position. More...
 
void write (std::ostream &os) const override
 Writes an IntersectionOfWalls to an output stream, for example a restart file. More...
 
std::string getName () const override
 Returns the name of the object, here the string "IntersectionOfWalls". More...
 
void writeVTK (VTKContainer &vtk) const override
 
- Public Member Functions inherited from BaseWall
 BaseWall ()
 Default constructor. More...
 
 BaseWall (const BaseWall &w)
 Copy constructor. More...
 
 ~BaseWall () override
 Default destructor. More...
 
virtual bool getDistanceNormalOverlap (const BaseParticle &P, Mdouble &distance, Vec3D &normal_return, Mdouble &overlap) const
 
virtual bool getDistanceNormalOverlapSuperquadric (const SuperQuadricParticle &p, Mdouble &distance, Vec3D &normal_return, Mdouble &overlap) const
 
virtual Vec3D getFurthestPointSuperQuadric (const Vec3D &normalBodyFixed, const Vec3D &axes, Mdouble eps1, Mdouble eps2) const
 
WallHandlergetHandler () const
 A function which returns the WallHandler that handles this BaseWall. More...
 
void setIndSpecies (unsigned int indSpecies) override
 Define the species of this wall using the index of the species in the SpeciesHandler in this DPMBase. More...
 
void setSpecies (const ParticleSpecies *species)
 Defines the species of the current wall. More...
 
bool isFixed () const override
 
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 of the wall. More...
 
virtual bool isLocal (Vec3D &min, Vec3D &max) const
 
bool getLinePlaneIntersect (Vec3D &intersect, const Vec3D &p0, const Vec3D &p1, const Vec3D &n, const Vec3D &p)
 
bool isInsideWallVTK (const Vec3D &point, const Vec3D &normal, const Vec3D &position) const
 
void projectOntoWallVTK (Vec3D &point0, const Vec3D &point1, const Vec3D &normal, const Vec3D &position) const
 
void intersectVTK (std::vector< Vec3D > &points, Vec3D normal, Vec3D position) const
 
virtual BaseInteractiongetInteractionWithSuperQuad (SuperQuadricParticle *p, unsigned timeStamp, InteractionHandler *interactionHandler)
 
void getVTK (std::vector< Vec3D > &points, std::vector< std::vector< double >> &triangleStrips)
 
const Vec3D getAxis () const
 
BaseInteractiongetInteractionWith (BaseParticle *p, unsigned timeStamp, InteractionHandler *interactionHandler) override
 Returns the interaction between this wall and a given particle, nullptr if there is no interaction. More...
 
virtual void actionsOnRestart ()
 No implementation but can be overidden in its derived classes. More...
 
virtual void actionsAfterParticleGhostUpdate ()
 No implementation but can be overidden in its derived classes. More...
 
virtual void handleParticleAddition (unsigned int id, BaseParticle *p)
 Handles the addition of particles to the particleHandler. More...
 
virtual void handleParticleRemoval (unsigned int id)
 Handles the addition of particles to the particleHandler. More...
 
virtual void checkInteractions (InteractionHandler *interactionHandler, unsigned int timeStamp)
 Check if all interactions are valid. More...
 
bool getVTKVisibility () const
 
void setVTKVisibility (bool vtkVisibility)
 
void addRenderedWall (BaseWall *w)
 
BaseWallgetRenderedWall (size_t i) const
 
std::vector< BaseWall * > getRenderedWalls () const
 
void removeRenderedWalls ()
 
void renderWall (VTKContainer &vtk)
 
void addParticlesAtWall (unsigned numElements=50)
 
void setVelocityControl (Vec3D forceGoal, Vec3D gainFactor, Vec3D baseVelocity)
 
virtual void writeWallDetailsVTK (VTKData &data) const
 
virtual void computeWear ()
 
- Public Member Functions inherited from BaseInteractable
 BaseInteractable ()
 Default BaseInteractable constructor. More...
 
 BaseInteractable (const BaseInteractable &p)
 Copy constructor. More...
 
 ~BaseInteractable () override
 Destructor, it simply destructs the BaseInteractable and all the objects it contains. More...
 
unsigned int getIndSpecies () const
 Returns the index of the species associated with the interactable object. More...
 
const ParticleSpeciesgetSpecies () const
 Returns a pointer to the species of this BaseInteractable. More...
 
void setSpecies (const ParticleSpecies *species)
 Sets the species of this BaseInteractable. More...
 
const Vec3DgetForce () const
 Returns the force on this BaseInteractable. More...
 
const Vec3DgetTorque () const
 Returns the torque on this BaseInteractable. More...
 
void setForce (const Vec3D &force)
 Sets the force on this BaseInteractable. More...
 
void setTorque (const Vec3D &torque)
 Sets the torque on this BaseInteractable. More...
 
void addForce (const Vec3D &addForce)
 Adds an amount to the force on this BaseInteractable. More...
 
void addTorque (const Vec3D &addTorque)
 Adds an amount to the torque on this BaseInteractable. More...
 
virtual void resetForceTorque (int numberOfOMPthreads)
 
void sumForceTorqueOMP ()
 
const Vec3DgetPosition () const
 Returns the position of this BaseInteractable. More...
 
const QuaterniongetOrientation () const
 Returns the orientation of this BaseInteractable. More...
 
virtual void setPosition (const Vec3D &position)
 Sets the position of this BaseInteractable. More...
 
void setOrientationViaNormal (Vec3D normal)
 Sets the orientation of this BaseInteractable by defining the vector that results from the rotation of the (1,0,0) vector. More...
 
void setOrientationViaEuler (Vec3D eulerAngle)
 Sets the orientation of this BaseInteractable by defining the euler angles. More...
 
virtual void setOrientation (const Quaternion &orientation)
 Sets the orientation of this BaseInteractable. More...
 
virtual void move (const Vec3D &move)
 Moves this BaseInteractable by adding an amount to the position. More...
 
virtual void rotate (const Vec3D &angularVelocityDt)
 Rotates this BaseInteractable. More...
 
const std::vector< BaseInteraction * > & getInteractions () const
 Returns a list of interactions which belong to this interactable. More...
 
void addInteraction (BaseInteraction *I)
 Adds an interaction to this BaseInteractable. More...
 
bool removeInteraction (BaseInteraction *I)
 Removes an interaction from this BaseInteractable. More...
 
void copyInteractionsForPeriodicParticles (const BaseInteractable &p)
 Copies interactions to this BaseInteractable whenever a periodic copy made. More...
 
void setVelocity (const Vec3D &velocity)
 set the velocity of the BaseInteractable. More...
 
void setAngularVelocity (const Vec3D &angularVelocity)
 set the angular velocity of the BaseInteractble. More...
 
void addVelocity (const Vec3D &velocity)
 adds an increment to the velocity. More...
 
void addAngularVelocity (const Vec3D &angularVelocity)
 add an increment to the angular velocity. More...
 
virtual const Vec3DgetVelocity () const
 Returns the velocity of this interactable. More...
 
virtual const Vec3DgetAngularVelocity () const
 Returns the angular velocity of this interactable. More...
 
void setPrescribedPosition (const std::function< Vec3D(double)> &prescribedPosition)
 Allows the position of an infinite mass interactable to be prescribed. More...
 
void applyPrescribedPosition (double time)
 Computes the position from the user defined prescribed position function. More...
 
void setPrescribedVelocity (const std::function< Vec3D(double)> &prescribedVelocity)
 Allows the velocity of an infinite mass interactable to be prescribed. More...
 
void applyPrescribedVelocity (double time)
 Computes the velocity from the user defined prescribed velocity function. More...
 
void setPrescribedOrientation (const std::function< Quaternion(double)> &prescribedOrientation)
 Allows the orientation of the infinite mass interactbale to be prescribed. More...
 
void applyPrescribedOrientation (double time)
 Computes the orientation from the user defined prescribed orientation function. More...
 
void setPrescribedAngularVelocity (const std::function< Vec3D(double)> &prescribedAngularVelocity)
 Allows the angular velocity of the infinite mass interactable to be prescribed. More...
 
void applyPrescribedAngularVelocity (double time)
 Computes the angular velocity from the user defined prescribed angular velocity. More...
 
virtual const Vec3D getVelocityAtContact (const Vec3D &contact) const
 Returns the velocity at the contact point, use by many force laws. More...
 
void integrateBeforeForceComputation (double time, double timeStep)
 This is part of integrate routine for objects with infinite mass. More...
 
void integrateAfterForceComputation (double time, double timeStep)
 This is part of the integration routine for objects with infinite mass. More...
 
virtual Mdouble getInvMass () const
 
virtual Mdouble getCurvature (const Vec3D &labFixedCoordinates) const
 
virtual bool isFaceContact (const Vec3D &normal) const
 
- Public Member Functions inherited from BaseObject
 BaseObject ()=default
 Default constructor. More...
 
 BaseObject (const BaseObject &p)=default
 Copy constructor, copies all the objects BaseObject contains. More...
 
virtual ~BaseObject ()=default
 virtual destructor More...
 
virtual void moveInHandler (unsigned int index)
 Except that it is virtual, it does the same thing as setIndex() does. More...
 
void setIndex (unsigned int index)
 Allows one to assign an index to an object in the handler/container. More...
 
void setId (unsigned long id)
 Assigns a unique identifier to each object in the handler (container) which remains constant even after the object is deleted from the container/handler. More...
 
unsigned int getIndex () const
 Returns the index of the object in the handler. More...
 
unsigned int getId () const
 Returns the unique identifier of any particular object. More...
 
void setGroupId (unsigned groupId)
 
unsigned getGroupId () const
 

Protected Attributes

std::vector< InfiniteWallwallObjects_
 The wall "segments"/directions that together make up the finite wall. More...
 
std::vector< Vec3DC_
 A vector that stores the intersection point of three different InfiniteWall. More...
 

Private Attributes

std::vector< Vec3DA_
 A vector that stores a point for each intersecting line between two different InfiniteWall. More...
 
std::vector< Vec3DAB_
 A vector that stores the direction of the intersecting lines between two different InfiniteWall. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from BaseWall
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. More...
 

Detailed Description

A IntersectionOfWalls is convex polygon defined as an intersection of InfiniteWall's.

It can be defined as the intersection of a set of InfiniteWall's, defined by the normal vector into the wall and a point on the wall. For example, the following gives a cube |x|<1 and |y|<1:

//for each wall, specify a normal and position vector
w.addObject(Vec3D(-1, 0, 0),Vec3D(1, 0, 0));
w.addObject(Vec3D(1, 0, 0),Vec3D(0, 0, 0));
w.addObject(Vec3D(0, -1, 0),Vec3D(0, 1, 0));
w.addObject(Vec3D(0, 1, 0),Vec3D(0, 0, 0));
wallHandler.copyAndAddObject(w);
A IntersectionOfWalls is convex polygon defined as an intersection of InfiniteWall's.
Definition: IntersectionOfWalls.h:59
void addObject(Vec3D normal, Vec3D point)
Adds a wall to the set of infinite walls, given a normal vector pointing into the wall (i....
Definition: IntersectionOfWalls.cc:138
Definition: Vector.h:51

A particle of radius *r* and position *x* touches an InfiniteWall with normal *n* and position *p* if \(p-n\cdot x\leq r\) (note 'touching particles' also includes particles that are completely enclosed inside the wall). A particle touches an IntersectionOfWalls if it touches all InfiniteWall objects (shown in the image below).

For a demonstration on how to use this class, see T8: Motion of a particle in a box with an obstacle and Flow through a 3D hourglass/silo (shown in the image below).

Constructor & Destructor Documentation

◆ IntersectionOfWalls() [1/3]

IntersectionOfWalls::IntersectionOfWalls ( )

Default constructor.

34 {
35  logger(DEBUG, "IntersectionOfWalls() constructed.");
36 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ DEBUG

References DEBUG, and logger.

Referenced by copy().

◆ IntersectionOfWalls() [2/3]

IntersectionOfWalls::IntersectionOfWalls ( const IntersectionOfWalls other)

Copy constructor.

Parameters
[in]otherThe IntersectionOfWalls that must be copied.
42  : BaseWall(other)
43 {
44  wallObjects_ = other.wallObjects_;
45  for (auto& wall : wallObjects_)
46  {
47  if (getHandler() != nullptr)
48  wall.setHandler(getHandler());
49  }
50  A_ = other.A_;
51  AB_ = other.AB_;
52  C_ = other.C_;
53  logger(DEBUG, "IntersectionOfWalls(IntersectionOfWalls&) constructed.");
54 }
WallHandler * getHandler() const
A function which returns the WallHandler that handles this BaseWall.
Definition: BaseWall.cc:134
BaseWall()
Default constructor.
Definition: BaseWall.cc:36
std::vector< Vec3D > AB_
A vector that stores the direction of the intersecting lines between two different InfiniteWall.
Definition: IntersectionOfWalls.h:234
std::vector< InfiniteWall > wallObjects_
The wall "segments"/directions that together make up the finite wall.
Definition: IntersectionOfWalls.h:219
std::vector< Vec3D > A_
A vector that stores a point for each intersecting line between two different InfiniteWall.
Definition: IntersectionOfWalls.h:227
std::vector< Vec3D > C_
A vector that stores the intersection point of three different InfiniteWall.
Definition: IntersectionOfWalls.h:242

References A_, AB_, C_, DEBUG, BaseWall::getHandler(), logger, and wallObjects_.

◆ IntersectionOfWalls() [3/3]

IntersectionOfWalls::IntersectionOfWalls ( const std::vector< normalAndPosition > &  walls,
const ParticleSpecies species 
)

Constructor setting values.

58 {
59  setSpecies(species);
60  for (auto wall : walls)
61  {
62  addObject(wall.normal, wall.position);
63  }
64 }
void setSpecies(const ParticleSpecies *species)
sets species of subwalls as well
Definition: IntersectionOfWalls.cc:72

References addObject(), and setSpecies().

◆ ~IntersectionOfWalls()

IntersectionOfWalls::~IntersectionOfWalls ( )
override

Destructor.

68 {
69  logger(DEBUG, "~IntersectionOfWalls() has been called.");
70 }

References DEBUG, and logger.

Member Function Documentation

◆ add3PointObject()

void IntersectionOfWalls::add3PointObject ( Vec3D  PointA,
Vec3D  PointB,
Vec3D  PointC 
)
Parameters
PointAfirst coordinate plane passes through;
PointBsecond coordinate plane passes through;
PointCthird coordinate plane passes through;

calls the IntersectionOfWalls::addObject(normal, point) by calculating the normal from these three coordinates

160 {
161  Vec3D SubtB = PointA - PointB;
162  Vec3D SubtC = PointA - PointC;
163 
164  Vec3D WallNormal = Vec3D::cross(SubtB, SubtC);
165  //Check if walls coordinates inline, if true Do not build wall and give error message.
166  if (WallNormal.getLengthSquared() == 0.0)
167  {
168  logger(ERROR,
169  "Error Building IntersectionOfWalls::add3PointObject out of 3 coordinates. Coordinates are in line, Wall not constructed.");
170  }
171  else
172  {
173  addObject(WallNormal, PointA);
174  }
175 
176 }
@ ERROR
static Mdouble getLengthSquared(const Vec3D &a)
Calculates the squared length of a Vec3D: .
Definition: Vector.h:332
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:163

References addObject(), Vec3D::cross(), ERROR, Vec3D::getLengthSquared(), and logger.

Referenced by addPlate(), addTetra(), and addTetraSTL().

◆ addObject() [1/3]

void IntersectionOfWalls::addObject ( Quaternion  orientation,
Vec3D  position 
)
Parameters
[in]normalThe normal to this wallObject.
[in]positionOne of the points of the wallObject.

Adds a wall to the set of finite walls, given an outward unit normal vector s.t. normal*x=normal*point for all x of the wallObject. First make the InfiniteWall, then compute all intersections, which are then stored in A_, AB_ and C_.

340 {
341  //n is the index of the new wall
342  std::size_t n = wallObjects_.size();
343  InfiniteWall w;
344  if (getSpecies()) w.setSpecies(getSpecies());
345  w.setOrientation(orientation);
346  w.setPosition(position);
347  wallObjects_.push_back(w);
349 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
virtual void setOrientation(const Quaternion &orientation)
Sets the orientation of this BaseInteractable.
Definition: BaseInteractable.h:260
virtual void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
Definition: BaseInteractable.h:239
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
Definition: BaseInteractable.h:108
void setSpecies(const ParticleSpecies *species)
Defines the species of the current wall.
Definition: BaseWall.cc:169
A infinite wall fills the half-space {point: (position_-point)*normal_<=0}.
Definition: InfiniteWall.h:48
void setPointsAndLines(unsigned int n)
Definition: IntersectionOfWalls.cc:351

References BaseInteractable::getSpecies(), n, BaseInteractable::setOrientation(), setPointsAndLines(), BaseInteractable::setPosition(), BaseWall::setSpecies(), and wallObjects_.

◆ addObject() [2/3]

void IntersectionOfWalls::addObject ( Vec3D  normal,
Mdouble  position 
)

Adds a wall to the set of finite walls, given an normal vector pointing into the wall (i.e. out of the flow domain), to give a plane defined by normal*x=position.

Deprecated:
Don't use this function, instead use the function addObject(Vec3D, Vec3D).
Parameters
[in]normalThe normal to the wallObject.
[in]positionThe position of the wallObject in the direction of the normal vector.
454 {
455  //logger(WARN, "This function is deprecated, use IntersectionOfWalls::addObject(Vec3D, Vec3D) instead.");
456  addObject(normal, position * normal);
457 }

References addObject().

◆ addObject() [3/3]

void IntersectionOfWalls::addObject ( Vec3D  normal,
Vec3D  point 
)

Adds a wall to the set of infinite walls, given a normal vector pointing into the wall (i.e. out of the simulation domain), going through the point, so that normal*x=normal*point.

Parameters
[in]normalThe normal to this wallObject.
[in]pointOne of the points of the wallObject.

Adds a wall to the set of finite walls, given an outward unit normal vector s.t. normal*x=normal*point for all x of the wallObject. First make the InfiniteWall, then compute all intersections, which are then stored in A_, AB_ and C_.

139 {
140  normal.normalise();
141 
142  //n is the index of the new wall
143  std::size_t n = wallObjects_.size();
144  InfiniteWall w;
145  if (getSpecies()) w.setSpecies(getSpecies());
146  w.set(normal, point);
147  wallObjects_.push_back(w);
149 }
void set(Vec3D normal, Vec3D point)
Defines a standard wall, given an outward normal vector s.t. normal*x=normal*point for all x of the w...
Definition: InfiniteWall.cc:118
void normalise()
Makes this Vec3D unit length.
Definition: Vector.cc:123

References BaseInteractable::getSpecies(), n, Vec3D::normalise(), InfiniteWall::set(), setPointsAndLines(), BaseWall::setSpecies(), and wallObjects_.

Referenced by add3PointObject(), NautaMixer::addBaseWall(), NautaMixer::addConeWall(), ChuteWithHopper::addHopper(), addObject(), VerticalMixerAngledBlades::addPrettyBlades(), NautaMixer::addScrew(), ChuteWithWedge::addWedge(), createOpenPrism(), createPrism(), GranuDrum::GranuDrum(), GranuHeap::GranuHeap(), IntersectionOfWalls(), main(), read(), WallHandler::readAndCreateOldObject(), ContractionWithPeriodicInflow::set_symmetric_contraction(), ChuteWithPeriodicInflowAndContraction::set_symmetric_contraction(), ChuteWithContraction::set_symmetric_contraction(), T_protectiveWall::setupInitialConditions(), AxisymmetricHopper::setupInitialConditions(), RotatingDrumWet::setupInitialConditions(), VerticalMixer::setupInitialConditions(), MaserRepeatedOutInMPI2Test::setupInitialConditions(), PeriodicBounaryEnteringMPIDomainTest::setupInitialConditions(), HourGlass::setupInitialConditions(), MinimalExampleDrum::setupInitialConditions(), GetDistanceAndNormalForIntersectionOfWalls::setupInitialConditions(), Polygon::setupInitialConditions(), Drum::setupInitialConditions(), Silo::setupInitialConditions(), ContactDetectionIntersectionOfWallsTest::setupInitialConditions(), TriangulatedScrewSelfTest::setupInitialConditions(), UnionOfWalls::setupInitialConditions(), RotatingDrum::setupInitialConditions(), protectiveWall::setupInitialConditions(), Tutorial11::setupInitialConditions(), Tutorial8::setupInitialConditions(), FullRestartTest::setupInitialConditions(), and MovingWalls::setupInitialConditions().

◆ addPlate()

void IntersectionOfWalls::addPlate ( const Vec3D PointA,
const Vec3D PointB,
const Vec3D PointC,
const Vec3D WallNormal,
const Mdouble Thickness,
int  wallidentifier 
)
299 {
300 
301  //Check if walls coordinates inline, if true Do not build wall and give error message. But keep continuing
302  if (WallNormal.getLengthSquared() == 0.0)
303  {
304  logger(WARN, "Error Building Plate number % out of 3 coordinates. Coordinates are in line, Wall not "
305  "constructed.", wallidentifier);
306  }
307  else
308  {
309  Vec3D PointAT = PointA - WallNormal * Thickness;
310  Vec3D PointBT = PointB - WallNormal * Thickness;
311  Vec3D PointCT = PointC - WallNormal * Thickness;
312 
313  //generate the base wall first through the input coordinates
314  add3PointObject(PointC, PointB, PointA);
315 
316  //add sidewalls
317  add3PointObject(PointA, PointB, PointAT);
318  add3PointObject(PointB, PointC, PointBT);
319  add3PointObject(PointC, PointA, PointCT);
320 
321 
322  //add opposite wall
323  add3PointObject(PointAT, PointBT, PointCT);
324 
325 
326  }
327 
328 
329 }
@ WARN
void add3PointObject(Vec3D PointA, Vec3D PointB, Vec3D PointC)
Definition: IntersectionOfWalls.cc:159

References add3PointObject(), Vec3D::getLengthSquared(), logger, and WARN.

◆ addTetra()

void IntersectionOfWalls::addTetra ( const Vec3D PointA,
const Vec3D PointB,
const Vec3D PointC,
Mdouble Thickness 
)

constructs a tetrahedron from 3 input coordinates

Parameters
PointAfirst coordinate plane passes through;
PointBsecond coordinate plane passes through;
PointCthird coordinate plane passes through;
Thicknessthe height of the apex

constructs a tethrahedron with the apex in the direction according to the right hand rule

261 {
262 
263  //generate other coordinate by finding the centre and shift it the distance thickness in the normal direction
264  //calculate normal
265  Vec3D SubtB = PointA - PointB;
266  Vec3D SubtC = PointA - PointC;
267 
268  Vec3D WallNormal = Vec3D::cross(SubtB, SubtC);
269 
270  //Check if walls coordinates inline, if true Do not build wall and give error message.
271  if (WallNormal.getLengthSquared() == 0.0)
272  {
273  logger(ERROR,
274  "Error Building IntersectionOfWalls::addTetra out of 3 coordinates. "
275  "Coordinates are in line, Wall not constructed.");
276  }
277  else
278  {
279  //calculate centroid
280  Vec3D mid = (PointA + PointB + PointC) / 3.0;
281  //shift centroid in normal direction
282  Vec3D midT = mid + WallNormal * Thickness;
283  //generate the base wall first through the input coordinates
284  add3PointObject(PointC, PointB, PointA);
285 
286  //add sidewalls
287  add3PointObject(PointA, midT, PointB);
288  add3PointObject(PointB, midT, PointC);
289  add3PointObject(PointC, midT, PointA);
290  }
291 }

References add3PointObject(), Vec3D::cross(), ERROR, Vec3D::getLengthSquared(), and logger.

◆ addTetraSTL()

void IntersectionOfWalls::addTetraSTL ( Vec3D  PointA,
Vec3D  PointB,
Vec3D  PointC,
Vec3D  WallNormal,
Mdouble  Thickness,
int  wallidentifier 
)

constructs a tetrahedron for an STL file input

Parameters
PointAfirst coordinate plane passes through;
PointBsecond coordinate plane passes through;
PointCthird coordinate plane passes through;
WallNormalthe normal of the wal of the plane, Please note that the Wallnormal input is defined inverse to other Mercury functions Due to the usage of this function for reading in STL files
Thicknessthe height of the apex
wallidentifierto identify which wall does not get constructed for bug finding in STL files

constructs a tethrahedron with the apex in minus normal direction.

193 {
194  //Check if wall coordinates inline, if true Do not build wall and give error message. But keep continuing
195  if (WallNormal.getLengthSquared() == 0.0)
196  {
197  logger(WARN, "Error Building Plate number % out of 3 coordinates. Coordinates are in line, Wall not "
198  "constructed", wallidentifier);
199  }
200  else
201  {
202  //do a check whether the normal follows the RHR (Right Hand Rule) or not
203  //todo: Bert Use this check a lot, possibly make a function of this
204  Vec3D SubtB = PointA - PointB;
205  Vec3D SubtC = PointA - PointC;
206 
207  Vec3D WallNormalRHR = Vec3D::cross(SubtB, SubtC);
208 
209  //normalise for easy check
210  WallNormalRHR.normalise();
211  WallNormal.normalise();
212 
213  //if RHRchecl is 1, wall normal and RHR normal are in same direction, if -1 theyre not, then point B and C need to be swapped
214  Mdouble RHRcheck = Vec3D::dot(WallNormalRHR, WallNormal);
215  //todo: Bert Officially need to check for other answers than 1, however, it will either be -1 or 1 in ideal case
216 
217  if (RHRcheck == 1)
218  {
219  //calculate centroid
220  Vec3D mid = (PointA + PointB + PointC) / 3.0;
221  //shift centroid in normal direction
222  //mental note: if Same direction as STL normal it should be subtracted to go IN the wall
223  Vec3D midT = mid - WallNormalRHR * Thickness;
224  //generate the base wall first through the input coordinates
225  add3PointObject(PointA, PointC, PointB);
226 
227  //add sidewalls
228  add3PointObject(PointA, midT, PointC);
229  add3PointObject(PointC, midT, PointB);
230  add3PointObject(PointB, midT, PointA);
231  }
232  else
233  {
234  //calculate centroid
235  Vec3D mid = (PointA + PointB + PointC) / 3.0;
236  //shift centroid in normal direction
237  //mental note: if opposite direction as STL normal it should be added to go IN the wall
238  Vec3D midT = mid + WallNormalRHR * Thickness;
239  //generate the base wall first through the input coordinates
240  add3PointObject(PointA, PointB, PointC);
241 
242  //add sidewalls
243  add3PointObject(PointA, midT, PointB);
244  add3PointObject(PointB, midT, PointC);
245  add3PointObject(PointC, midT, PointA);
246  }
247 
248  }
249 }
double Mdouble
Definition: GeneralDefine.h:34
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:76

References add3PointObject(), Vec3D::cross(), Vec3D::dot(), Vec3D::getLengthSquared(), logger, Vec3D::normalise(), and WARN.

◆ clear()

void IntersectionOfWalls::clear ( )

Removes all parts of the walls.

103 {
104  wallObjects_.clear();
105  A_.clear();
106  AB_.clear();
107  C_.clear();
109 }
void removeRenderedWalls()
Definition: BaseWall.cc:589

References A_, AB_, C_, BaseWall::removeRenderedWalls(), and wallObjects_.

Referenced by createOpenPrism().

◆ copy()

IntersectionOfWalls * IntersectionOfWalls::copy ( ) const
overridevirtual

Wall copy method. It calls the copy constructor of this Wall, useful for polymorphism.

Returns
pointer to a IntersectionOfWalls object allocated using new.

Implements BaseWall.

Reimplemented in ScrewsymmetricIntersectionOfWalls.

98 {
99  return new IntersectionOfWalls(*this);
100 }
IntersectionOfWalls()
Default constructor.
Definition: IntersectionOfWalls.cc:33

References IntersectionOfWalls().

Referenced by operator=().

◆ createOpenPrism() [1/2]

void IntersectionOfWalls::createOpenPrism ( std::vector< Vec3D points)

Creates an open prism which is a polygon between the points, except the first and last point, and extends infinitely in the direction perpendicular to the first and second wall. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly.

Parameters
[in]pointsA vector of 3D-vectors which contains the points between which the polygon is drawn.

Create an open prism which is a polygon with no connection between the first and last point, and extending infinitely in the direction perpendicular to the first and second wall. Do this by first computing in which direction the wall must be extended infinitely, then call createOpenPrism(points, prismAxis).

496 {
497  Vec3D prismAxis = Vec3D::cross(
498  Vec3D::getUnitVector(points[1] - points[0]),
499  Vec3D::getUnitVector(points[2] - points[0]));
500  createOpenPrism(points, prismAxis);
501 }
void createOpenPrism(std::vector< Vec3D > points, Vec3D prismAxis)
Creates an open prism which is a polygon between the points, except the first and last point,...
Definition: IntersectionOfWalls.cc:467
static Vec3D getUnitVector(const Vec3D &a)
Returns a unit Vec3D based on a.
Definition: Vector.cc:345

References createOpenPrism(), Vec3D::cross(), and Vec3D::getUnitVector().

◆ createOpenPrism() [2/2]

void IntersectionOfWalls::createOpenPrism ( std::vector< Vec3D points,
Vec3D  prismAxis 
)

Creates an open prism which is a polygon between the points, except the first and last point, and extends infinitely in the PrismAxis direction. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly.

Parameters
[in]pointsA vector of 3D-vectors which contains the points between which the polygon is drawn.
[in]prismAxisA 3D-vector which represents the direction in which the prism is extended infinitely.

Create an open prism which is a polygon with no connection between the first and last point, and extending infinitely in the other direction, which is defined as PrismAxis. Do this by adding the walls between the consecutive points one by one.

468 {
469  clear();
470  //note: use i+1 < points.size() instead of i < points.size()-1, otherwise it creates havoc if point has zero entries.
471  for (unsigned int i = 0; i + 1 < points.size(); i++)
472  addObject(Vec3D::cross(points[i] - points[i + 1], prismAxis), points[i]);
473 }
void clear()
Removes all parts of the walls.
Definition: IntersectionOfWalls.cc:102
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References addObject(), clear(), Vec3D::cross(), and constants::i.

Referenced by VerticalMixerStraightBlades::addBlades(), VerticalMixerAngledBlades::addBlades(), createOpenPrism(), createPrism(), HourGlass2D::setupInitialConditions(), HourGlass::setupInitialConditions(), Tutorial11::setupInitialConditions(), and MovingIntersectionOfWallsUnitTest_Basic::setupInitialConditions().

◆ createPrism() [1/2]

void IntersectionOfWalls::createPrism ( std::vector< Vec3D points)

Creates an open prism which is a polygon between the points and extends infinitely in the direction perpendicular to the first and second wall. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly.

Parameters
[in]pointsA vector of 3D-vectors which contains the points between which the polygon is drawn.

Create an open prism which is a polygon, and extending infinitely in the direction perpendicular to the first and second wall. Do this by first computing in which direction the wall must be extended infinitely, then call createOpenPrism(points, prismAxis).

511 {
512  Vec3D prismAxis = Vec3D::cross(
513  Vec3D::getUnitVector(points[1] - points[0]),
514  Vec3D::getUnitVector(points[2] - points[0]));
515  createPrism(points, prismAxis);
516 }
void createPrism(std::vector< Vec3D > points, Vec3D prismAxis)
Creates an open prism which is a polygon between the points and extends infinitely in the PrismAxis d...
Definition: IntersectionOfWalls.cc:482

References createPrism(), Vec3D::cross(), and Vec3D::getUnitVector().

◆ createPrism() [2/2]

void IntersectionOfWalls::createPrism ( std::vector< Vec3D points,
Vec3D  prismAxis 
)

Creates an open prism which is a polygon between the points and extends infinitely in the PrismAxis direction. Note that if you view from inside of your geometry, the shape formed by points has to be convex, otherwise it will not create the wall correctly.

Parameters
[in]pointsA vector of 3D-vectors which contains the points between which the polygon is drawn.
[in]prismAxisA 3D-vector which represents the direction in which the prism is extended infinitely.

Create an open prism which is a polygon and extending infinitely in the other direction, which is defined as PrismAxis. Do this by first creating an open prism and then connect the last and the first point.

483 {
484  createOpenPrism(points, prismAxis);
485  addObject(Vec3D::cross(points.back() - points.front(), prismAxis), points.front());
486 }

References addObject(), createOpenPrism(), and Vec3D::cross().

Referenced by VerticalMixerAngledBlades::addPrettyBlades(), createPrism(), AxisymmetricWallSelfTest::setGeometry(), and Tutorial12::setupInitialConditions().

◆ getDistanceAndNormal() [1/2]

bool IntersectionOfWalls::getDistanceAndNormal ( const BaseParticle p,
Mdouble distance,
Vec3D normal_return 
) const
overridevirtual

Compute the distance from the wall for a given BaseParticle and return if there is a collision. If there is a collision, also return the normal vector.

Parameters
[in]pBaseParticle we want to calculate the distance and whether it collided of.
[out]distanceThe distance of the BaseParticle to this wall.
[out]normal_returnIf there was a collision, the normal vector to this wall will be placed here.
Returns
A boolean which says whether or not there was a collision.

This function computes whether or not there is a collision between a given BaseParticle and this IntersectionOfWalls. If there is a collision, this function also computes the distance between the BaseParticle and IntersectionOfWalls and the normal of the IntersectionOfWalls at the intersection point. It does this by calling IntersectionOfWalls::getDistanceAndNormal(const Vec3D& , Mdouble , Mdouble&, Vec3D&) const. Since this function should be called before calculating any Particle-Wall interactions, it can also be used to set the normal vector in case of curved walls.

Todo:
do this for all walls

Implements BaseWall.

Reimplemented in ScrewsymmetricIntersectionOfWalls.

533 {
534  //transform coordinates into position-orientation frame
535  Vec3D position = p.getPosition() - getPosition();
536  getOrientation().rotateBack(position);
539  if (getDistanceAndNormal(position, p.getRadius() + s->getInteractionDistance(), distance, normal_return))
540  {
541  getOrientation().rotate(normal_return);
542  return true;
543  }
544  else
545  {
546  return false;
547  }
548 }
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.
Definition: BaseInteractable.h:230
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:218
Mdouble getRadius() const
Returns the particle's radius.
Definition: BaseParticle.h:348
BaseSpecies is the class from which all other species are derived.
Definition: BaseSpecies.h:50
Mdouble getInteractionDistance() const
returns the largest separation distance at which adhesive short-range forces can occur.
Definition: BaseSpecies.h:146
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1427
bool getDistanceAndNormal(const BaseParticle &p, Mdouble &distance, Vec3D &normal_return) const override
Compute the distance from the wall for a given BaseParticle and return if there is a collision....
Definition: IntersectionOfWalls.cc:532
void rotate(Vec3D &position) const
Definition: Quaternion.cc:563
void rotateBack(Vec3D &position) const
Definition: Quaternion.cc:610
std::enable_if<!std::is_pointer< typename U::MixedSpeciesType >::value, typename U::MixedSpeciesType * >::type getMixedObject(const U *S, const U *T)
Definition: SpeciesHandler.h:74

References BaseHandler< T >::getDPMBase(), BaseWall::getHandler(), BaseSpecies::getInteractionDistance(), SpeciesHandler::getMixedObject(), BaseInteractable::getOrientation(), BaseInteractable::getPosition(), BaseParticle::getRadius(), BaseInteractable::getSpecies(), Quaternion::rotate(), Quaternion::rotateBack(), and DPMBase::speciesHandler.

Referenced by AxisymmetricIntersectionOfWalls::getDistanceAndNormal(), HorizontalBaseScrew::getDistanceAndNormal(), and ScrewsymmetricIntersectionOfWalls::getDistanceAndNormal().

◆ getDistanceAndNormal() [2/2]

bool IntersectionOfWalls::getDistanceAndNormal ( const Vec3D position,
Mdouble  wallInteractionRadius,
Mdouble distance,
Vec3D normal_return 
) const

Compute the distance from the wall for a given BaseParticle and return if there is an interaction. If there is an interaction, also return the normal vector.

Parameters
[in]positionThe position of the object there is possible an interaction with.
[in]wallInteractionRadiusThe maximum distance between the IntersectionOfWalls and the input argument position for which there is an interaction.
[out]distanceThe distance of the object at position to this wall.
[out]normal_returnIf there was an interaction, the normal vector to this wall will be placed here.
Returns
A boolean which says whether or not there was an interaction.

This function computes whether a particle at the given position (position) and radius (wallInteractionRadius) overlaps with the IntersectionOfWalls.

  • First, the distances to each InfiniteWall is computed, and the three walls with the largest distances (smallest overlaps) are identified (distance, distance2, distance3, id, id2, id3).
  • If the largest distance is bigger than the wallInteractionRadius, there is no contact. This, if any distance>wallInteractionRadius is detected we return false.
  • If the second-largest distance is bigger than the wallInteractionRadius, it is a face contact (contact with a single wall.
  • Otherwise, we need to determine if it is a edge or vertex contact. In the latter two cases, the function returns true, and the distance and normal vector is returned.
569 {
570  if (wallObjects_.empty())
571  {
572  logger(DEBUG, "Empty IntersectionOfWalls");
573  return false;
574  }
575 
576  distance = -1e20;
577  Mdouble distance2 = -1e20;
578  Mdouble distance3 = -1e20;
579  Mdouble distanceCurrent;
580  unsigned int id = 0;
581  unsigned int id2 = 0;
582  unsigned int id3 = 0;
583 
584  //For each wall we calculate the distance (distanceCurrent). To compute The walls with the minimal overlap
585  //The object has to touch each wall each wall (distanceCurrent) and keep the minimum distance (distance) and wall index (id
586  for (unsigned int i = 0; i < wallObjects_.size(); i++)
587  {
588  // Calculate distance to each wall (distanceCurrent);
589  distanceCurrent = wallObjects_[i].getDistance(position);
590  // The object has to touch each wall (distanceCurrent >= wallInteractionRadius), otherwise return false (i.e. no contact)
591  // This means that for each InfiniteWall in wallObjects_, the particle is either "inside"
592  // the wall or touching it. If not, there is no interaction.
593  if (distanceCurrent >= wallInteractionRadius)
594  {
595  return false;
596  }
597  // Find out which of the InfiniteWalls is interacting with the particle.
598  // Keep the minimum distance (distance) and wall index (id)
599  // and store up to two walls (id2, id3) and their distances (distance2, distance3),
600  // if the possible contact point is near the intersection between id and id2 (and id3)
601  if (distanceCurrent > distance)
602  {
603  if (distance > -wallInteractionRadius) //if distance was set previously
604  {
605  if (distance2 > -wallInteractionRadius) //if distance2 was set previously
606  {
607  distance3 = distance2;
608  id3 = id2;
609  }
610  distance2 = distance;
611  id2 = id;
612  }
613  distance = distanceCurrent;
614  id = i;
615  }
616  else if (distanceCurrent < -wallInteractionRadius)
617  {
618  continue;
619  }
620  else if (distanceCurrent > distance2)
621  {
622  if (distance2 > -wallInteractionRadius) //if distance2 was set previously
623  {
624  distance3 = distance2;
625  id3 = id2;
626  }
627  distance2 = distanceCurrent;
628  id2 = i;
629  }
630  else if (distanceCurrent > distance3)
631  {
632  distance3 = distanceCurrent;
633  id3 = i;
634  }
635  }
636 
637  //If we are here, the closest wall is id;
638  //if distance2>-P.Radius (and distance3>-P.Radius), the possible contact point
639  // is near the intersection between id and id2 (and id3)
640  if (distance2 > -wallInteractionRadius)
641  {
642  //D is the point on wall id closest to P
643  Vec3D D = position + wallObjects_[id].getNormal() * distance;
644  //If the distance of D to id2 is positive, the contact is with the intersection
645  bool intersection_with_id2 = (wallObjects_[id2].getDistance(D) > 0.0);
646 
647  if (distance3 > -wallInteractionRadius && (wallObjects_[id3].getDistance(D) > 0.0))
648  {
649  //E is the point on wall id2 closest to P
650  Vec3D E = position + wallObjects_[id2].getNormal() * distance2;
651  //If the distance of D to id2 is positive, the contact is with the intersection
652  bool intersection_with_id3 = (wallObjects_[id3].getDistance(E) > 0.0);
653 
654  if (intersection_with_id2)
655  {
656  if (intersection_with_id3)
657  {
658  //possible contact is with intersection of id,id2,id3
659  //we know id2<id3
660  if (id2 > id3)
661  {
662  auto id = id2;
663  id2 = id3;
664  id3 = id;
665  }
666  unsigned int index =
667  (id < id2) ? ((id3 - 2) * (id3 - 1) * id3 / 6 + (id2 - 1) * id2 / 2 + id) :
668  (id < id3) ? ((id3 - 2) * (id3 - 1) * id3 / 6 + (id - 1) * id / 2 + id2) :
669  ((id - 2) * (id - 1) * id / 6 + (id3 - 1) * id3 / 2 + id2);
670  normal_return = position - C_[index];
671  distance = sqrt(normal_return.getLengthSquared());
672  if (distance <= wallInteractionRadius) //note what if nan?
673  {
674  normal_return /= -distance;
675  return true; //contact with id,id2,id3
676  }
677  else
678  {
679  if (distance == distance)
680  return false;
681  }
682  }
683  }
684  else
685  {
686  intersection_with_id2 = true;
687  distance2 = distance3;
688  id2 = id3;
689  }
690  }
691 
692  if (intersection_with_id2)
693  { //possible contact is with intersection of id,id2
694  unsigned int index = (id > id2) ? ((id - 1) * id / 2 + id2) : ((id2 - 1) * id2 / 2 + id);
695  Vec3D AC = position - A_[index];
696  normal_return = AC - AB_[index] * Vec3D::dot(AC, AB_[index]);
697  distance = sqrt(normal_return.getLengthSquared());
698  if (distance <= wallInteractionRadius) //note what if nan?
699  {
700  normal_return /= -distance;
701  return true; //contact with id,id2,id3
702  }
703  else
704  {
705  if (distance == distance)
706  return false;
707  }
708  }
709  }
710  //contact is with id
711  normal_return = wallObjects_[id].getNormal();
712  return true;
713 }
dominoes D
Definition: Domino.cpp:76
double E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:64

References A_, AB_, C_, D, DEBUG, Vec3D::dot(), Global_Physical_Variables::E, Vec3D::getLengthSquared(), constants::i, logger, and wallObjects_.

◆ getName()

std::string IntersectionOfWalls::getName ( ) const
overridevirtual

Returns the name of the object, here the string "IntersectionOfWalls".

Returns
The string "IntersectionOfWalls".

Implements BaseObject.

Reimplemented in ScrewsymmetricIntersectionOfWalls.

790 {
791  return "IntersectionOfWalls";
792 }

◆ getNumberOfObjects()

unsigned int IntersectionOfWalls::getNumberOfObjects ( )

Returns the number of objects.

\detail Suppose your simulation adds to an IntersectionOfWalls after a certain time or condition is met. Checking the number of objects is useful for checking if this has happened yet, when restarting.

126 {
127  return wallObjects_.size();
128 }

References wallObjects_.

◆ operator=()

IntersectionOfWalls & IntersectionOfWalls::operator= ( const IntersectionOfWalls other)

Copy assignment operator.

Parameters
[in]otherThe IntersectionOfWalls that must be copied.
85 {
86  logger(DEBUG, "IntersectionOfWalls::operator= called.");
87  if (this == &other)
88  {
89  return *this;
90  }
91  return *(other.copy());
92 }
IntersectionOfWalls * copy() const override
Wall copy method. It calls the copy constructor of this Wall, useful for polymorphism.
Definition: IntersectionOfWalls.cc:97

References copy(), DEBUG, and logger.

◆ read()

void IntersectionOfWalls::read ( std::istream &  is)
overridevirtual

Move the IntersectionOfWalls to a new position, which is a Vec3D from the old position.

Todo:
currently the IntersectionOfWall is special for moving and rotating; should we remove that specialty?

Reads an IntersectionOfWalls from an input stream, for example a restart file.

 \param[in] move A reference to a Vec3D that denotes the direction and length
 it should be moved with.
 \details A function that moves the InterSectionOfWalls in a certain direction
 by both moving the walls and all intersections. Note that the directions of the
 intersections are not moved since they don't change when moving the IntersectionOfWalls
 as a whole.
 \todo We should use the position_ and orientation_ of the IntersectionOfWalls;
 that way, IntersectionOfWalls can be moved with the standard BaseInteractable::move function,
 getting rid of an anomaly in the code and removing the virtual from the move function. \author weinhartt
&zwj;/

void IntersectionOfWalls::move(const Vec3D& move) { BaseInteractable::move(move); for (Vec3D& a : A_) { a += move; } for (Vec3D& c : C_) { c += move; } for (InfiniteWall& o : wallObjects_) { o.move(move); } }

/*!

Parameters
[in]isThe input stream from which the IntersectionOfWalls is read, usually a restart file.

Reimplemented from BaseWall.

Reimplemented in ScrewsymmetricIntersectionOfWalls.

747 {
748  BaseWall::read(is);
749  std::string dummy;
750  int n;
751  is >> dummy >> n;
752 
753  Vec3D normal;
754  Vec3D position;
755  for (int i = 0; i < n; i++)
756  {
757  is >> dummy;
758  if (dummy != "normal")
759  {
760  Quaternion orientation;
761  is >> position >> dummy >> orientation;
762  addObject(orientation, position);
763  }
764  else
765  {
766  is >> normal >> dummy >> position;
767  addObject(normal, position);
768  }
769  }
770 }
void read(std::istream &is) override
Function that reads a BaseWall from an input stream, usually a restart file.
Definition: BaseWall.cc:78
This class contains the 4 components of a quaternion and the standard operators and functions needed ...
Definition: Quaternion.h:63

References addObject(), constants::i, n, and BaseWall::read().

Referenced by AxisymmetricIntersectionOfWalls::read(), HorizontalBaseScrew::read(), and ScrewsymmetricIntersectionOfWalls::read().

◆ setHandler()

void IntersectionOfWalls::setHandler ( WallHandler handler)
overridevirtual

A function which sets the WallHandler for this BaseWall.

Setting the WallHandler also sets the DPMBase and therefore the SpeciesHandler for the species. This wall's species pointer is updated to the new SpeciesHandler.

Parameters
[in]handler- A pointer to the WallHandler that we want to handle this wall.

Reimplemented from BaseWall.

112 {
113  BaseWall::setHandler(wallHandler);
114  for (InfiniteWall& w : wallObjects_)
115  {
116  w.setHandler(wallHandler);
117  }
118 }
virtual void setHandler(WallHandler *handler)
A function which sets the WallHandler for this BaseWall.
Definition: BaseWall.cc:125

References BaseWall::setHandler(), and wallObjects_.

◆ setPointsAndLines()

void IntersectionOfWalls::setPointsAndLines ( unsigned int  n)
352 {
353  // AB[n*(n-1)/2+m] is the direction of the intersecting line between walls m and n, m<n
354  // A[n*(n-1)/2+m] is a point on the intersecting line between walls m and n, m<n
355  // See http://www.netcomuk.co.uk/~jenolive/vect18d.html for finding the line where two planes meet
356  AB_.resize(n * (n + 1) / 2); //0 + 1 + 2 + ... + indexNew, total number of walls you need
357  A_.resize(n * (n + 1) / 2);
358  for (std::size_t m = 0; m < n; m++)
359  {
360  std::size_t id = (n - 1) * n / 2 + m;
361  //first we cross the wall normals and normalise to obtain AB
362  AB_[id] = Vec3D::cross(wallObjects_[m].getNormal(), wallObjects_[n].getNormal());
363  AB_[id] /= sqrt(AB_[id].getLengthSquared());
364  //then we find a point A (using AB*x=0 as a third plane)
365  Mdouble invdet = 1.0 / (+wallObjects_[n].getNormal().X *
366  (wallObjects_[m].getNormal().Y * AB_[id].Z - AB_[id].Y * wallObjects_[m].getNormal().Z)
367  - wallObjects_[n].getNormal().Y * (wallObjects_[m].getNormal().X * AB_[id].Z -
368  wallObjects_[m].getNormal().Z * AB_[id].X)
369  + wallObjects_[n].getNormal().Z * (wallObjects_[m].getNormal().X * AB_[id].Y -
370  wallObjects_[m].getNormal().Y * AB_[id].X));
371 
372  A_[id] = Vec3D(+(wallObjects_[m].getNormal().Y * AB_[id].Z - AB_[id].Y * wallObjects_[m].getNormal().Z) *
374  - (wallObjects_[n].getNormal().Y * AB_[id].Z - wallObjects_[n].getNormal().Z * AB_[id].Y) *
375  Vec3D::dot(wallObjects_[m].getPosition(), wallObjects_[m].getNormal())
376  + (wallObjects_[n].getNormal().Y * wallObjects_[m].getNormal().Z -
377  wallObjects_[n].getNormal().Z * wallObjects_[m].getNormal().Y) * 0.0,
378  -(wallObjects_[m].getNormal().X * AB_[id].Z - wallObjects_[m].getNormal().Z * AB_[id].X) *
380  + (wallObjects_[n].getNormal().X * AB_[id].Z - wallObjects_[n].getNormal().Z * AB_[id].X) *
381  Vec3D::dot(wallObjects_[m].getPosition(), wallObjects_[m].getNormal())
382  - (wallObjects_[n].getNormal().X * wallObjects_[m].getNormal().Z -
383  wallObjects_[m].getNormal().X * wallObjects_[n].getNormal().Z) * 0.0,
384  +(wallObjects_[m].getNormal().X * AB_[id].Y - AB_[id].X * wallObjects_[m].getNormal().Y) *
386  - (wallObjects_[n].getNormal().X * AB_[id].Y - AB_[id].X * wallObjects_[n].getNormal().Y) *
387  Vec3D::dot(wallObjects_[m].getPosition(), wallObjects_[m].getNormal())
388  + (wallObjects_[n].getNormal().X * wallObjects_[m].getNormal().Y -
389  wallObjects_[m].getNormal().X * wallObjects_[n].getNormal().Y) * 0.0) * invdet;
390  }
391 
392  // C[(n-2)*(n-1)*n/6+(m-1)*m/2+l] is a point intersecting walls l, m and n, l<m<n
393  C_.resize((n - 1) * n * (n + 1) / 6);
394  for (std::size_t m = 0; m < n; m++)
395  {
396  for (std::size_t l = 0; l < m; l++)
397  {
398  std::size_t id = (n - 2) * (n - 1) * n / 6 + (m - 1) * m / 2 + l;
399  Mdouble invdet = 1.0 / (+wallObjects_[n].getNormal().X *
400  (wallObjects_[m].getNormal().Y * wallObjects_[l].getNormal().Z -
401  wallObjects_[l].getNormal().Y * wallObjects_[m].getNormal().Z)
402  - wallObjects_[n].getNormal().Y *
403  (wallObjects_[m].getNormal().X * wallObjects_[l].getNormal().Z -
404  wallObjects_[m].getNormal().Z * wallObjects_[l].getNormal().X)
405  + wallObjects_[n].getNormal().Z *
406  (wallObjects_[m].getNormal().X * wallObjects_[l].getNormal().Y -
407  wallObjects_[m].getNormal().Y * wallObjects_[l].getNormal().X));
408  C_[id] = Vec3D(+(wallObjects_[m].getNormal().Y * wallObjects_[l].getNormal().Z -
409  wallObjects_[l].getNormal().Y * wallObjects_[m].getNormal().Z) *
411  - (wallObjects_[n].getNormal().Y * wallObjects_[l].getNormal().Z -
412  wallObjects_[n].getNormal().Z * wallObjects_[l].getNormal().Y) *
413  Vec3D::dot(wallObjects_[m].getPosition(), wallObjects_[m].getNormal())
414  + (wallObjects_[n].getNormal().Y * wallObjects_[m].getNormal().Z -
415  wallObjects_[n].getNormal().Z * wallObjects_[m].getNormal().Y) *
416  Vec3D::dot(wallObjects_[l].getPosition(), wallObjects_[l].getNormal()),
417  -(wallObjects_[m].getNormal().X * wallObjects_[l].getNormal().Z -
418  wallObjects_[m].getNormal().Z * wallObjects_[l].getNormal().X) *
420  + (wallObjects_[n].getNormal().X * wallObjects_[l].getNormal().Z -
421  wallObjects_[n].getNormal().Z * wallObjects_[l].getNormal().X) *
422  Vec3D::dot(wallObjects_[m].getPosition(), wallObjects_[m].getNormal())
423  - (wallObjects_[n].getNormal().X * wallObjects_[m].getNormal().Z -
424  wallObjects_[m].getNormal().X * wallObjects_[n].getNormal().Z) *
425  Vec3D::dot(wallObjects_[l].getPosition(), wallObjects_[l].getNormal()),
426  +(wallObjects_[m].getNormal().X * wallObjects_[l].getNormal().Y -
427  wallObjects_[l].getNormal().X * wallObjects_[m].getNormal().Y) *
429  - (wallObjects_[n].getNormal().X * wallObjects_[l].getNormal().Y -
430  wallObjects_[l].getNormal().X * wallObjects_[n].getNormal().Y) *
431  Vec3D::dot(wallObjects_[m].getPosition(), wallObjects_[m].getNormal())
432  + (wallObjects_[n].getNormal().X * wallObjects_[m].getNormal().Y -
433  wallObjects_[m].getNormal().X * wallObjects_[n].getNormal().Y) *
434  Vec3D::dot(wallObjects_[l].getPosition(), wallObjects_[l].getNormal())) * invdet;
435  }
436  }
437 
438  logger(VERBOSE, "%", *this);
439  for (const InfiniteWall& w : wallObjects_)
440  logger(VERBOSE, "wallObject %, %", w.getNormal(), w.getPosition());
441  for (Vec3D v : A_)
442  logger(VERBOSE, "A %", v);
443  for (Vec3D v : AB_)
444  logger(VERBOSE, "AB %", v);
445  for (Vec3D v : C_)
446  logger(VERBOSE, "C %", v);
447 }
@ VERBOSE
@ Y
Definition: StatisticsVector.h:42
@ X
Definition: StatisticsVector.h:42
@ Z
Definition: StatisticsVector.h:42

References A_, AB_, C_, Vec3D::cross(), Vec3D::dot(), BaseInteractable::getPosition(), logger, n, VERBOSE, wallObjects_, X, Y, and Z.

Referenced by addObject().

◆ setSpecies()

void IntersectionOfWalls::setSpecies ( const ParticleSpecies species)

sets species of subwalls as well

73 {
74  BaseWall::setSpecies(species);
75  for (auto wall : wallObjects_)
76  {
77  wall.setSpecies(species);
78  }
79 }

References BaseWall::setSpecies(), and wallObjects_.

Referenced by NautaMixer::addBaseWall(), VerticalMixerStraightBlades::addBlades(), VerticalMixerAngledBlades::addBlades(), NautaMixer::addConeWall(), ChuteWithHopper::addHopper(), VerticalMixerAngledBlades::addPrettyBlades(), NautaMixer::addScrew(), ChuteWithWedge::addWedge(), GranuDrum::GranuDrum(), GranuHeap::GranuHeap(), IntersectionOfWalls(), main(), WallHandler::readAndCreateOldObject(), AxisymmetricWallSelfTest::setGeometry(), T_protectiveWall::setupInitialConditions(), AxisymmetricHopper::setupInitialConditions(), RotatingDrumWet::setupInitialConditions(), VerticalMixer::setupInitialConditions(), HourGlass2D::setupInitialConditions(), HourGlass::setupInitialConditions(), MinimalExampleDrum::setupInitialConditions(), GetDistanceAndNormalForIntersectionOfWalls::setupInitialConditions(), Polygon::setupInitialConditions(), Drum::setupInitialConditions(), Silo::setupInitialConditions(), ContactDetectionIntersectionOfWallsTest::setupInitialConditions(), UnionOfWalls::setupInitialConditions(), RotatingDrum::setupInitialConditions(), protectiveWall::setupInitialConditions(), Tutorial11::setupInitialConditions(), Tutorial12::setupInitialConditions(), Tutorial8::setupInitialConditions(), FullRestartTest::setupInitialConditions(), MovingIntersectionOfWallsUnitTest_Basic::setupInitialConditions(), and MovingWalls::setupInitialConditions().

◆ write()

void IntersectionOfWalls::write ( std::ostream &  os) const
overridevirtual

Writes an IntersectionOfWalls to an output stream, for example a restart file.

Parameters
[in]osThe output stream where the IntersectionOfWalls must be written to, usually a restart file.

Reimplemented from BaseWall.

Reimplemented in ScrewsymmetricIntersectionOfWalls.

777 {
778  BaseWall::write(os);
779  os << " numIntersectionOfWalls " << wallObjects_.size();
780  for (const auto& wallObject : wallObjects_)
781  {
782  os << " position " << wallObject.getPosition() << " orientation " << wallObject.getOrientation();
783  }
784 }
void write(std::ostream &os) const override
Function that writes a BaseWall to an output stream, usually a restart file.
Definition: BaseWall.cc:100

References wallObjects_, and BaseWall::write().

Referenced by AxisymmetricIntersectionOfWalls::write(), HorizontalBaseScrew::write(), and ScrewsymmetricIntersectionOfWalls::write().

◆ writeVTK()

void IntersectionOfWalls::writeVTK ( VTKContainer vtk) const
overridevirtual

adds extra information to the points and triangleStrips vectors needed to plot the wall in vtk format

Parameters
pointsCoordinates of the vertices of the triangulated surfaces (in the VTK file this is called POINTS)
triangleStripsIndices of three vertices forming one triangulated surface (in the VTK file this is called CELL)

Reimplemented from BaseWall.

Reimplemented in ScrewsymmetricIntersectionOfWalls.

795 {
796  Vec3D max = getHandler()->getDPMBase()->getMax()-getPosition();
797  Vec3D min = getHandler()->getDPMBase()->getMin()-getPosition();
798  for (auto wall = wallObjects_.begin(); wall != wallObjects_.end(); wall++)
799  {
800  std::vector<Vec3D> points;
801  wall->createVTK(points, min, max);
802  for (auto other = wallObjects_.begin(); other != wallObjects_.end(); other++)
803  {
804  if (other != wall)
805  {
806  intersectVTK(points, -other->getNormal(), other->getPosition());
807  }
808  }
809  //rotate into real frame
810  for (auto& p : points)
811  {
812  getOrientation().rotate(p);
813  p += getPosition();
814  }
815  wall->addToVTK(points, vtk);
816  }
817 }
void intersectVTK(std::vector< Vec3D > &points, Vec3D normal, Vec3D position) const
Definition: BaseWall.cc:241
Vec3D getMax() const
Definition: DPMBase.h:670
Vec3D getMin() const
Definition: DPMBase.h:664

References BaseHandler< T >::getDPMBase(), BaseWall::getHandler(), DPMBase::getMax(), DPMBase::getMin(), BaseInteractable::getOrientation(), BaseInteractable::getPosition(), BaseWall::intersectVTK(), Quaternion::rotate(), and wallObjects_.

Member Data Documentation

◆ A_

std::vector<Vec3D> IntersectionOfWalls::A_
private

A vector that stores a point for each intersecting line between two different InfiniteWall.

A[n*(n-1)/2+m] is a point on the intersecting line between walls m and n, m<n.

Referenced by clear(), getDistanceAndNormal(), IntersectionOfWalls(), and setPointsAndLines().

◆ AB_

std::vector<Vec3D> IntersectionOfWalls::AB_
private

A vector that stores the direction of the intersecting lines between two different InfiniteWall.

AB[n*(n-1)/2+m] is the direction of the intersecting line between walls m and n, m<n.

Referenced by clear(), getDistanceAndNormal(), IntersectionOfWalls(), and setPointsAndLines().

◆ C_

std::vector<Vec3D> IntersectionOfWalls::C_
protected

A vector that stores the intersection point of three different InfiniteWall.

C[(n-2)*(n-1)*n/6+(m-1)*m/2+l] is a point intersecting walls l, m and n, l<m<n

Referenced by clear(), getDistanceAndNormal(), IntersectionOfWalls(), and setPointsAndLines().

◆ wallObjects_

std::vector<InfiniteWall> IntersectionOfWalls::wallObjects_
protected

The wall "segments"/directions that together make up the finite wall.

An intersection of walls exists of a number of infinite walls that are cut of at the intersection points. These InfiniteWall are saved in this vector called iWObjects_.

Referenced by addObject(), clear(), getDistanceAndNormal(), getNumberOfObjects(), IntersectionOfWalls(), setHandler(), setPointsAndLines(), setSpecies(), write(), AxisymmetricIntersectionOfWalls::writeVTK(), HorizontalBaseScrew::writeVTK(), writeVTK(), and ScrewsymmetricIntersectionOfWalls::writeVTK().


The documentation for this class was generated from the following files: