MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AxisymmetricIntersectionOfWalls.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
27 #include "Particles/BaseParticle.h"
28 #include "WallHandler.h"
29 #include "DPMBase.h"
30 
32 {
33  logger(DEBUG, "AxisymmetricIntersectionOfWalls() finished");
34 }
35 
40  : IntersectionOfWalls(other)
41 {
42  logger(DEBUG, "AxisymmetricIntersectionOfWalls(const AxisymmetricIntersectionOfWalls &p) finished");
43 }
44 
45 AxisymmetricIntersectionOfWalls::AxisymmetricIntersectionOfWalls(Vec3D position, Vec3D orientation, std::vector<AxisymmetricIntersectionOfWalls::normalAndPosition> walls, const ParticleSpecies* species)
46  : IntersectionOfWalls(walls, species)
47 {
48  setPosition(position);
49  setOrientation(orientation);
50 }
51 
53 {
54  logger(DEBUG, "~AxisymmetricIntersectionOfWalls() finished.");
55 }
56 
61 {
62  if (this == &other)
63  {
64  return *this;
65  }
66  else
67  {
68  return *(other.copy());
69  }
70 }
71 
76 {
77  return new AxisymmetricIntersectionOfWalls(*this);
78 }
79 
91 {
92  //transform to axisymmetric coordinates
93  //move the coordinate system to the axis origin, so pOrigin=(xhat,yhat,zhat)
94  Vec3D pOrigin = p.getPosition() -getPosition();
95  Mdouble normal = Vec3D::dot(pOrigin, getOrientation());
96  //tangential is the projection into the (xhat,yhat) plane
97  Vec3D tangentialUnitVector = pOrigin - normal * getOrientation();
98  Mdouble tangential = tangentialUnitVector.getLength();
99  if (tangential!=0.0)
100  tangentialUnitVector /= tangential;
101  else //in this case the tangential vector is irrelevant
102  logger(WARN, "Warning: Particle % is exactly on the symmetry axis of wall %", p.getIndex(), getIndex());
103  Vec3D transformedPosition = Vec3D(tangential, 0.0, normal); //now P=(r,phi,zhat) is cylindrical
104  Vec3D transformedNormal;
105  //determine wall distance, normal and contact in axissymmetric coordinates
106  //and transform from axisymmetric coordinates
107  if (!IntersectionOfWalls::getDistanceAndNormal(transformedPosition, p.getWallInteractionRadius(), distance, transformedNormal))
108  {
109  //if not in contact
110  return false;
111  }
112  else
113  {
114  //if in contact
115  normalReturn = transformedNormal.Z * getOrientation() + transformedNormal.X * tangentialUnitVector;
116  return true;
117  }
118 }
119 
125 {
127 }
128 
133 void AxisymmetricIntersectionOfWalls::write(std::ostream& os) const
134 {
136 }
137 
142 {
143  return "AxisymmetricIntersectionOfWalls";
144 }
145 
147  //define the box in the rz plane
148  double x[2] = {min.X, max.X};
149  double y[2] = {min.Y, max.Y};
150  double z[2] = {min.Z, max.Z};
151  Vec3D o = getOrientation();
152  min.X = 0;
153  Mdouble maxXSquared = 0; //to be set
154  min.Y = 0;
155  max.Y = 0.001;
156  min.Z = Vec3D::dot(max,o); //to be set
157  max.Z = min.Z; //to be set
158  for (unsigned i=0; i<2; i++)
159  for (unsigned j=0; j<2; j++)
160  for (unsigned k=0; k<2; k++) {
161  Vec3D p = Vec3D(x[i],y[j],z[k])-getPosition();
162  double Z = Vec3D::dot(p,o);
163  double XSquared = Vec3D::getLengthSquared(p-Z*o);
164  if (XSquared>maxXSquared) maxXSquared=XSquared;
165  if (Z<min.Z) min.Z=Z;
166  if (Z>max.Z) max.Z=Z;
167  }
168  max.X = sqrt(maxXSquared);
169 }
170 
172 {
173  for (auto wall=wallObjects_.begin(); wall!=wallObjects_.end(); wall++)
174  {
175  //plot each of the intersecting walls
176  std::vector<Vec3D> myPoints;
177 
178  //first create a slice of non-rotated wall in the xz plane, 0<y<1
179  Vec3D min = getHandler()->getDPMBase()->getMin();
180  Vec3D max = getHandler()->getDPMBase()->getMax();
181  convertLimits(min, max);
182 
183  //create the basic slice for the first wall using the InfiniteWall routine
184  wall->createVTK (myPoints,min,max);
185 
186  //create intersections with the other walls, similar to the IntersectionOfWalls routine
187  for (auto other=wallObjects_.begin(); other!=wallObjects_.end(); other++)
188  {
189  if (other!=wall)
190  {
191  intersectVTK(myPoints, -other->getNormal(), other->getPosition());
192  }
193  }
194 
195  //only keep the y=0 values
196  std::vector<Vec3D> rzVec;
197  for (auto& p: myPoints)
198  {
199  if (p.Y==0)
200  {
201  rzVec.push_back(p);
202  }
203  }
204  if (rzVec.size()==0)
205  return;
206 
207  //create 60 points on the unit circle
208  unsigned nr = 60;
209  struct XY {
210  double X;
211  double Y;
212  };
213  std::vector<XY> xyVec;
214  for (unsigned ir=0; ir<nr; ir++) {
215  Mdouble angle = 2.0 * constants::pi * ir/nr;
216  xyVec.push_back({cos(angle),sin(angle)});
217  }
218 
219  //now create rings of points on the axisym. shape
221  unsigned nPoints = vtk.points.size();
222  Vec3D p;
223  for (auto rz : rzVec)
224  {
225  for (auto xy : xyVec)
226  {
227  p = getPosition();
228  p.X += rz.X * xy.X;
229  p.Y += rz.X * xy.Y;
230  p.Z += rz.Z;
231  vtk.points.push_back(p);
232  }
233  }
234 
235  //finally create the connectivity matri to plot shell-like triangle strips.
236  unsigned nz = rzVec.size();
237  unsigned nCells = vtk.triangleStrips.size();
238  vtk.triangleStrips.reserve(nCells+(nz-1));
239  for (unsigned iz=0; iz<nz-1; iz++) {
240  std::vector<double> cell;
241  cell.reserve(2*nr+2);
242  for (unsigned ir=0; ir<nr; ir++) {
243  cell.push_back(nPoints+ir+iz*nr);
244  cell.push_back(nPoints+ir+(iz+1)*nr);
245  }
246  cell.push_back(nPoints+iz*nr);
247  cell.push_back(nPoints+(iz+1)*nr);
248  vtk.triangleStrips.push_back(cell);
249  }
250  }
251 
252 }
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:108
Mdouble X
the vector components
Definition: Vector.h:52
A IntersectionOfWalls is convex polygon defined as an intersection of InfiniteWall's.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void convertLimits(Vec3D &min, Vec3D &max) const
void setOrientation(const Vec3D &orientation)
Sets the orientation of this BaseInteractable.
void read(std::istream &is) override
Reads an IntersectionOfWalls from an input stream, for example a restart file.
Vec3D getMin() const
Return the "bottom left" corner of the domain, a vector with xMin_, yMin_ and zMin_.
Definition: DPMBase.h:330
void write(std::ostream &os) const final
outputs wall
double Mdouble
bool getDistanceAndNormal(const BaseParticle &P, Mdouble &distance, Vec3D &normal_return) const final
Computes the distance from the wall for a given BaseParticle and returns true if there is a collision...
std::string getName() const final
Returns the name of the object.
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...
void intersectVTK(std::vector< Vec3D > &points, const Vec3D normal, const Vec3D position) const
Definition: BaseWall.cc:163
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:167
Mdouble getLengthSquared() const
Calculates the squared length of this Vec3D: .
Definition: Vector.cc:300
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
const Vec3D & getOrientation() const
Returns the orientation of this BaseInteractable.
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:414
Mdouble getWallInteractionRadius() const
Returns the interaction radius for interaction with walls. See also BaseParticle::getInteractionRadiu...
std::vector< InfiniteWall > wallObjects_
The wall "segments"/directions that together make up the finite wall.
Mdouble cos(Mdouble x)
Definition: ExtendedMath.cc:60
WallHandler * getHandler() const
A function which returns the WallHandler that handles this BaseWall.
Definition: BaseWall.cc:85
void writeVTK(VTKContainer &vtk) const override
Mdouble sin(Mdouble x)
Definition: ExtendedMath.cc:42
const Mdouble pi
Definition: ExtendedMath.h:42
AxisymmetricIntersectionOfWalls * copy() const final
Wall copy method. It calls the copy constructor of this Wall, useful for polymorphism.
std::vector< std::vector< double > > triangleStrips
Definition: BaseWall.h:36
AxisymmetricIntersectionOfWalls & operator=(const AxisymmetricIntersectionOfWalls &other)
Copy assignment operator.
void read(std::istream &is) final
reads wall
Vec3D getMax() const
Return the "upper right" corner of the domain, a vector with xMin_, yMin_ and zMin_.
Definition: DPMBase.h:335
A AxisymmetricIntersectionOfWalls is an axisymmetric wall, defined by rotating a twodimensional Inter...
Mdouble Y
Definition: Vector.h:52
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
std::vector< Vec3D > points
Definition: BaseWall.h:35
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:543
Mdouble Z
Definition: Vector.h:52
void write(std::ostream &os) const override
Writes an IntersectionOfWalls to an output stream, for example a restart file.