MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WallHandler.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2020, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 
27 #include <Math/Helpers.h>
29 #include <Walls/TriangleWall.h>
32 #include "WallHandler.h"
33 #include "Walls/BaseWall.h"
34 #include "Walls/CylindricalWall.h"
37 #include "Walls/InfiniteWall.h"
39 #include "Walls/NurbsWall.h"
40 #include "Walls/Screw.h"
41 #include "Walls/Coil.h"
42 #include "DPMBase.h"
43 #include "Walls/VChute.h"
44 #include "BinaryReader.h"
45 #include "STLTriangle.h"
46 
51 {
53  clear();
54 #ifdef DEBUG_CONSTRUCTOR
55  std::cerr << "WallHandler::WallHandler() finished" << std::endl;
56 #endif
57 }
58 
66 {
68  clear();
69  setDPMBase(WH.getDPMBase());
71 #ifdef DEBUG_CONSTRUCTOR
72  std::cerr << "WallHandler::WallHandler(const WallHandler&) finished" << std::endl;
73 #endif
74 }
75 
83 {
84  if (this != &rhs)
85  {
86  clear();
87  setDPMBase(rhs.getDPMBase());
89  }
90  return *this;
91 #ifdef DEBUG_CONSTRUCTOR
92  std::cerr << "WallHandler::operator =(const WallHandler&) finished" << std::endl;
93 #endif
94 }
95 
97 {
98 #ifdef DEBUG_CONSTRUCTOR
99  std::cerr << "WallHandler::~WallHandler() finished" << std::endl;
100 #endif
101 }
102 
109 {
110  if (W->getSpecies() == nullptr)
111  {
112  logger(WARN, "WARNING: The wall with ID % that is added in WallHandler::addObject "
113  "does not have a species yet. Please make sure that you have "
114  "set the species somewhere in the driver code.", W->getId());
115  }
116  //Puts the wall in the Wall list
118  //set the particleHandler pointer
119  W->setHandler(this);
120 }
121 
122 BaseWall* WallHandler::createObject(const std::string& type)
123 {
124  if (type == "CylindricalWall")
125  {
126  return new CylindricalWall;
127  }
128  else if (type == "AxisymmetricIntersectionOfWalls")
129  {
131  }
132  else if (type == "ScrewsymmetricIntersectionOfWalls")
133  {
135  }
136  else if (type == "IntersectionOfWalls")
137  {
138  return new IntersectionOfWalls;
139  }
140  else if (type == "BasicIntersectionOfWalls")
141  {
142  return new BasicIntersectionOfWalls;
143  }
144  else if (type == "BasicUnionOfWalls")
145  {
146  return new BasicUnionOfWalls;
147  }
148  else if (type == "InfiniteWall")
149  {
150  return new InfiniteWall;
151  }
152  else if (type == "InfiniteWallWithHole")
153  {
154  return new InfiniteWallWithHole;
155  }
156  else if (type == "Screw")
157  {
158  return new Screw;
159  }
160  else if (type == "Coil")
161  {
162  return new Coil;
163  }
164  else if (type == "TriangleWall")
165  {
166  return new TriangleWall;
167  }
168  else if (type == "VChute")
169  {
170  return new VChute;
171  }
172  else if (type == "NurbsWall")
173  {
174  return new NurbsWall();
175  }
176  //for backward compatibility (before svnversion ~2360)
177  else if (type == "numFiniteWalls")
178  {
179  return new BasicIntersectionOfWalls;
180  }
182  // else if (!getDPMBase()->readUserDefinedWall(type,is))
183  else
184  {
185  logger(WARN, "Wall type: % not understood in restart file", type);
186  return nullptr;
187  }
188 }
189 
191 {
192  std::string type;
193  is >> type;
194  logger(DEBUG, "WallHandler::readAndAddObject(is): reading type %.", type);
195 
196  //for backward compatibility (before svnversion ~2360)
197  if (type == "numFiniteWalls")
198  {
199  return readAndCreateOldObject(is);
200  }
201  else
202  {
203  BaseWall* wall = createObject(type);
204  //check if wall is user-defined
205  if (wall == nullptr)
206  {
207  wall = getDPMBase()->readUserDefinedWall(type);
208  }
209  //throw warning if wall could not be found
210  if (wall == nullptr)
211  {
212  std::string line;
213  getline(is, line);
214  logger(WARN, "This wall could not be read; dummy wall is inserted instead:\n%%", type, line);
215  BaseWall* wall = new InfiniteWall;
216  wall->setHandler(this);
217  wall->setSpecies(getDPMBase()->speciesHandler.getObject(0));
218  return wall;
219  }
220  wall->setHandler(this);
221  is >> *wall;
222  wall->setSpecies(getDPMBase()->speciesHandler.getObject(wall->getIndSpecies()));
223  return wall;
224  }
225 }
226 
237 {
238  //read in next line
239  std::stringstream line;
241  logger(VERBOSE, line.str());
242 
243  std::string dummy;
244  unsigned int numWalls;
245  Mdouble position;
246  Vec3D normal;
247  line >> numWalls;
248 
249  if (numWalls == 0)
250  {
251  InfiniteWall* wall = new InfiniteWall();
252  wall->setSpecies(getDPMBase()->speciesHandler.getObject(0));
253  line >> dummy >> normal >> dummy >> position;
254  wall->set(normal, position * normal);
255  return wall;
256  }
257  else
258  {
260  wall->setSpecies(getDPMBase()->speciesHandler.getObject(0));
261  for (unsigned int i = 0; i < numWalls; ++i)
262  {
263  line >> dummy >> normal >> dummy >> position;
264  wall->addObject(normal, position * normal);
265  }
266  return wall;
267  }
268 }
269 
276 void WallHandler::readAndAddObject(std::istream& is)
277 {
278  BaseWall* o = readAndCreateObject(is);
279  unsigned int id = o->getId();
280  addObject(o);
281  getLastObject()->setId(id);
282 }
283 
287 std::string WallHandler::getName() const
288 {
289  return "WallHandler";
290 }
291 
298 {
299  const std::string fileName = getDPMBase()->getName() + "BoundingBox.vtu";
300  //logger(INFO, "% writing vtk file for bounding box: %",
301  // getDPMBase()->getTime(), fileName);
302  std::fstream file;
303  file.open(fileName.c_str(), std::ios::out);
304  if (file.fail())
305  {
307  logger(WARN, "Error in writeToFile: file could not be opened");
308  }
309  file << "<?xml version=\"1.0\"?>\n\n";
310  file << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
311  file << "<UnstructuredGrid>\n";
312  file << "<Piece NumberOfPoints=\"8\" NumberOfCells=\"1\">\n";
313  file << "<Points>\n";
314  file << " <DataArray type=\"Float32\" Name=\"Position\" NumberOfComponents=\"3\" format=\"ascii\">\n";
315  Vec3D P[2] = {getDPMBase()->getMax(), getDPMBase()->getMin()};
316  for (auto& i : P)
317  {
318  for (auto& j : P)
319  {
320  for (auto& k : P)
321  {
322  Vec3D p = Vec3D(i.X, j.Y, k.Z);
323  file << '\t' << p << '\n';
324  }
325  }
326  }
328  file << " </DataArray>\n";
329  file << "</Points>\n";
330  file << "<Cells>\n";
331  file <<
332  " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
333  file << "\t0 1 3 2 0 4 5 1 5 7 3 7 6 2 6 4\n";
334  file << " </DataArray>\n";
335  file << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
336  file <<
337  "\t16\n"; //offset into the connectivity array for the end of each cell.
338  file << " </DataArray>\n";
339  file << " <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
340  file << "\t4\n";
341  file << " </DataArray>\n";
342  file << "</Cells>\n";
343  file << "</Piece>\n";
344  file << "</UnstructuredGrid>\n";
345  file << "</VTKFile>\n";
346  file.close();
347 }
348 
357 unsigned WallHandler::readTriangleWall(std::string filename, ParticleSpecies* species, Mdouble scaleFactor, Vec3D centerOfRotation, Vec3D velocity, Vec3D angularVelocity)
358 {
359  const unsigned groupId = getNextGroupId();
360  std::string fileType = filename.substr(filename.find_last_of('.') + 1);
361 
362  //define a default triangle wall
363  TriangleWall triangleWall;
364  triangleWall.setSpecies(species);
365  triangleWall.setVelocity(velocity);
366  triangleWall.setAngularVelocity(angularVelocity);
367  triangleWall.setGroupId(groupId);
368 
369  if (helpers::lower(fileType) == "vtk")
370  {
371  //try open the input file
372  std::fstream file;
373  file.open(filename.c_str(), std::ios::in);
374  logger.assert_always(file.is_open(), "File opening failed: %", filename);
375 
376  //skip the header lines
377  std::string dummy;
378  getline(file, dummy);
379  getline(file, dummy);
380  getline(file, dummy);
381  getline(file, dummy);
382 
383  //read vertices, apply scaling
384  unsigned num;
385  file >> dummy >> num >> dummy;
386  std::vector<Vec3D> vertex;
387  vertex.reserve(num);
388  Vec3D v;
389  for (unsigned i = 0; i < num; i++)
390  {
391  file >> v.X >> v.Y >> v.Z;
392  v *= scaleFactor;
393  vertex.push_back(v);
394  }
395 
396  //read faces
397  unsigned n = getSize();
398  file >> dummy >> num >> dummy;
399  unsigned id0, id1, id2;
400  for (unsigned i = 0; i < num; i++)
401  {
402  file >> dummy >> id0 >> id1 >> id2;
403  triangleWall.setVertices(vertex[id0], vertex[id1], vertex[id2], centerOfRotation);
404  copyAndAddObject(triangleWall);
405  }
406 
407  //close file
408  file.close();
409 
410  logger(INFO, "Read in % walls from %", getSize() - n,filename);
411 
412  }
413  else if (helpers::lower(fileType) == "stl")
414  {
415 
416  BinaryReader file(filename);
417 
418  STLTriangle triangle;
419 
420  std::string header = file.readString(80);
421  unsigned numTriangles = file.readUnsignedInt(4);
422 
423  for (unsigned i = 0; i < numTriangles; i++)
424  {
425  triangle.normal.x() = file.readFloat(4);
426  triangle.normal.y() = file.readFloat(4);
427  triangle.normal.z() = file.readFloat(4);
428 
429 
430  triangle.vertex1.x() = file.readFloat(4);
431  triangle.vertex1.y() = file.readFloat(4);
432  triangle.vertex1.z() = file.readFloat(4);
433 
434  triangle.vertex2.x() = file.readFloat(4);
435  triangle.vertex2.y() = file.readFloat(4);
436  triangle.vertex2.z() = file.readFloat(4);
437 
438 
439  triangle.vertex3.x() = file.readFloat(4);
440  triangle.vertex3.y() = file.readFloat(4);
441  triangle.vertex3.z() = file.readFloat(4);
442 
443  triangle.vertex1 *= scaleFactor;
444  triangle.vertex2 *= scaleFactor;
445  triangle.vertex3 *= scaleFactor;
446 
447  //add to triangle wall
448  triangleWall.setVertices(triangle.vertex1, triangle.vertex2, triangle.vertex3, centerOfRotation);
449  copyAndAddObject(triangleWall);
450 
451  //Now ignore (read) the two dummy characters
452  file.ignoreChar(2);
453 
454  }
455 
456  logger(INFO, "Read in % walls from %", numTriangles,filename);
457 
458  }
459  else
460  {
461 
462  logger(ERROR, "File type of % must be vtk or stl");
463 
464  }
465 
466  return groupId;
467 }
A TriangleWall is convex polygon defined as an intersection of InfiniteWall's.
Definition: TriangleWall.h:56
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.h:125
Mdouble X
the vector components
Definition: Vector.h:65
std::string lower(std::string s)
Definition: Helpers.cc:55
This function defines a wall via a NurbsSurface.
Definition: NurbsWall.h:35
unsigned int readUnsignedInt(unsigned int size)
read the next so many bytes as a unsined int
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
A IntersectionOfWalls is convex polygon defined as an intersection of InfiniteWall's.
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
void readAndAddObject(std::istream &is) final
Create a new wall in the WallHandler, based on the information provided in a restart file...
Definition: WallHandler.cc:276
This function defines an Archimedes' screw in the z-direction from a (constant) starting point...
Definition: Screw.h:43
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
This is a class defining walls.
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
void addObject(BaseWall *W) final
Adds a BaseWall to the WallHandler.
Definition: WallHandler.cc:108
Vec3D getMin() const
Definition: DPMBase.h:623
Vec3D vertex3
Definition: STLTriangle.h:57
const std::complex< Mdouble > i
Definition: ExtendedMath.h:50
~WallHandler() final
Destructor, it destructs the WallHandler and all BaseWall it contains.
Definition: WallHandler.cc:96
virtual void setHandler(WallHandler *handler)
A function which sets the WallHandler for this BaseWall.
Definition: BaseWall.cc:127
const std::string & getName() const
Returns the name of the file. Does not allow to change it though.
Definition: DPMBase.cc:389
This is a class defining walls.
void addObject(Vec3D normal, Vec3D point)
Adds a wall to the set of infinite walls, given a normal vector pointing into the wall (i...
BaseWall * readAndCreateObject(std::istream &is)
Create a new wall, based on the information provided in a restart file.
Definition: WallHandler.cc:190
Mdouble & z()
RW reference to Z.
Definition: Vector.h:368
std::string getName() const final
Returns the name of the handler, namely the string "WallHandler".
Definition: WallHandler.cc:287
Vec3D vertex1
Definition: STLTriangle.h:55
void setSpecies(const ParticleSpecies *species)
sets species of subwalls as well
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
Vec3D vertex2
Definition: STLTriangle.h:56
unsigned readTriangleWall(std::string filename, ParticleSpecies *species, Mdouble scaleFactor=1, Vec3D centerOfRotation={0, 0, 0}, Vec3D velocity={0, 0, 0}, Vec3D angularVelocity={0, 0, 0})
Reads triangulated walls from vtk or stl files, and converts them into a set of TriangleWalls.
Definition: WallHandler.cc:357
Definition: VChute.h:34
Use ScrewsymmetricIntersectionOfWalls to define screwsymmetric walls, such as cylinders, cones, etc.
WallHandler & operator=(const WallHandler &rhs)
Assignment operator that copies the pointer to the DPMBase and all BaseWall in the given WallHandler...
Definition: WallHandler.cc:82
BaseWall * readAndCreateOldObject(std::istream &is)
Create a new wall, based on the information from old-style restart data.
Definition: WallHandler.cc:236
virtual BaseWall * readUserDefinedWall(const std::string &type) const
Allows you to read in a wall defined in a Driver directory; see USER/Luca/ScrewFiller.
Definition: DPMBase.h:279
void getLineFromStringStream(std::istream &in, std::stringstream &out)
Reads a line from one stringstream into another, and prepares the latter for reading in...
Definition: Helpers.cc:424
unsigned getNextGroupId()
Should be called each time you assign a groupId. Returns the value of nextGroupId_ and increases next...
Definition: BaseHandler.h:293
double readFloat(unsigned int size)
read the next so many bytes as a double (not in this case they were saves as a float orgainlly) ...
Vec3D normal
Definition: STLTriangle.h:54
Mdouble & x()
RW reference to X.
Definition: Vector.h:344
void writeVTKBoundingBox() const
Writes a bounding box around the domain into a vtk file.
Definition: WallHandler.cc:297
WallHandler()
Default constructor, it creates an empty WallHandler.
Definition: WallHandler.cc:50
void setVertices(Vec3D A, Vec3D B, Vec3D C)
Sets member variables such that the wall represents a triangle with vertices A, B, C.
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject(const U &object)
Creates a copy of a Object and adds it to the BaseHandler.
Basic class for walls.
Definition: BaseWall.h:47
Mdouble & y()
RW reference to Y.
Definition: Vector.h:356
Vec3D getMax() const
Definition: DPMBase.h:629
Use AxisymmetricIntersectionOfWalls to Screw Screw::read Screw::read Screw::read define axisymmetric ...
Mdouble Y
Definition: Vector.h:65
Container to store all BaseWall.
Definition: WallHandler.h:42
void setGroupId(unsigned groupId)
Definition: BaseObject.h:131
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...
This gives functionality to read information from binary formats like STL etc. This class is complete...
Definition: BinaryReader.h:36
void ignoreChar(unsigned int size)
read and ignore the next number of characters
virtual void addObject(T *object)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:431
This is a class defining walls.
Definition: InfiniteWall.h:47
BaseWall * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
void copyContentsFromOtherHandler(const BaseHandler< BaseWall > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Definition: Vector.h:49
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:725
std::string readString(unsigned int numChar)
reads the next so many Characters (bytes) as a std::string
Definition: BinaryReader.cc:80
Mdouble Z
Definition: Vector.h:65
void setAngularVelocity(const Vec3D &angularVelocity)
set the angular velocity of the BaseInteractble.
This class defines a coil in the z-direction from a (constant) starting point, a (constant) length L...
Definition: Coil.h:40
void setId(unsigned long id)
Assigns a unique identifier to each object in the handler (container) which remains constant even aft...
Definition: BaseObject.cc:72
virtual void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
void setSpecies(const ParticleSpecies *species)
Defines the species of the current wall.
Definition: BaseWall.cc:171