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>
30 #include <Walls/MeshTriangle.h>
33 #include "WallHandler.h"
34 #include "Walls/BaseWall.h"
35 #include "Walls/CylindricalWall.h"
38 #include "Walls/InfiniteWall.h"
40 #include "Walls/NurbsWall.h"
41 #include "Walls/Screw.h"
42 #include "Walls/Coil.h"
43 #include "DPMBase.h"
44 #include "Walls/VChute.h"
45 #include "BinaryReader.h"
46 #include "STLTriangle.h"
47 
52 {
54  clear();
55 #ifdef DEBUG_CONSTRUCTOR
56  std::cerr << "WallHandler::WallHandler() finished" << std::endl;
57 #endif
58 }
59 
67 {
69  clear();
70  setDPMBase(WH.getDPMBase());
72 #ifdef DEBUG_CONSTRUCTOR
73  std::cerr << "WallHandler::WallHandler(const WallHandler&) finished" << std::endl;
74 #endif
75 }
76 
84 {
85  if (this != &rhs)
86  {
87  clear();
88  setDPMBase(rhs.getDPMBase());
90  }
91  return *this;
92 #ifdef DEBUG_CONSTRUCTOR
93  std::cerr << "WallHandler::operator =(const WallHandler&) finished" << std::endl;
94 #endif
95 }
96 
98 {
99 #ifdef DEBUG_CONSTRUCTOR
100  std::cerr << "WallHandler::~WallHandler() finished" << std::endl;
101 #endif
102 }
103 
110 {
111  if (W->getSpecies() == nullptr)
112  {
113  logger(WARN, "WARNING: The wall with ID % that is added in WallHandler::addObject "
114  "does not have a species yet. Please make sure that you have "
115  "set the species somewhere in the driver code.", W->getId());
116  }
117  //Puts the wall in the Wall list
119  //set the particleHandler pointer
120  W->setHandler(this);
121 }
122 
123 BaseWall* WallHandler::createObject(const std::string& type)
124 {
125  if (type == "CylindricalWall")
126  {
127  return new CylindricalWall;
128  }
129  else if (type == "AxisymmetricIntersectionOfWalls")
130  {
132  }
133  else if (type == "ScrewsymmetricIntersectionOfWalls")
134  {
136  }
137  else if (type == "IntersectionOfWalls")
138  {
139  return new IntersectionOfWalls;
140  }
141  else if (type == "BasicIntersectionOfWalls")
142  {
143  return new BasicIntersectionOfWalls;
144  }
145  else if (type == "BasicUnionOfWalls")
146  {
147  return new BasicUnionOfWalls;
148  }
149  else if (type == "InfiniteWall")
150  {
151  return new InfiniteWall;
152  }
153  else if (type == "InfiniteWallWithHole")
154  {
155  return new InfiniteWallWithHole;
156  }
157  else if (type == "Screw")
158  {
159  return new Screw;
160  }
161  else if (type == "Coil")
162  {
163  return new Coil;
164  }
165  else if (type == "TriangleWall")
166  {
167  return new TriangleWall;
168  }
169  else if (type == "MeshTriangle")
170  {
171  return new MeshTriangle;
172  }
173  else if (type == "VChute")
174  {
175  return new VChute;
176  }
177  else if (type == "NurbsWall")
178  {
179  return new NurbsWall();
180  }
181  //for backward compatibility (before svnversion ~2360)
182  else if (type == "numFiniteWalls")
183  {
184  return new BasicIntersectionOfWalls;
185  }
187  // else if (!getDPMBase()->readUserDefinedWall(type,is))
188  else
189  {
190  logger(WARN, "Wall type: % not understood in restart file", type);
191  return nullptr;
192  }
193 }
194 
196 {
197  std::string type;
198  is >> type;
199  logger(DEBUG, "WallHandler::readAndAddObject(is): reading type %.", type);
200 
201  //for backward compatibility (before svnversion ~2360)
202  if (type == "numFiniteWalls")
203  {
204  return readAndCreateOldObject(is);
205  }
206  else
207  {
208  BaseWall* wall = createObject(type);
209  //check if wall is user-defined
210  if (wall == nullptr)
211  {
212  wall = getDPMBase()->readUserDefinedWall(type);
213  }
214  //throw warning if wall could not be found
215  if (wall == nullptr)
216  {
217  std::string line;
218  getline(is, line);
219  logger(WARN, "This wall could not be read; dummy wall is inserted instead:\n%%", type, line);
220  BaseWall* wall = new InfiniteWall;
221  wall->setHandler(this);
222  wall->setSpecies(getDPMBase()->speciesHandler.getObject(0));
223  return wall;
224  }
225  wall->setHandler(this);
226  is >> *wall;
227  wall->setSpecies(getDPMBase()->speciesHandler.getObject(wall->getIndSpecies()));
228  return wall;
229  }
230 }
231 
242 {
243  //read in next line
244  std::stringstream line;
246  logger(VERBOSE, line.str());
247 
248  std::string dummy;
249  unsigned int numWalls;
250  Mdouble position;
251  Vec3D normal;
252  line >> numWalls;
253 
254  if (numWalls == 0)
255  {
256  InfiniteWall* wall = new InfiniteWall();
257  wall->setSpecies(getDPMBase()->speciesHandler.getObject(0));
258  line >> dummy >> normal >> dummy >> position;
259  wall->set(normal, position * normal);
260  return wall;
261  }
262  else
263  {
265  wall->setSpecies(getDPMBase()->speciesHandler.getObject(0));
266  for (unsigned int i = 0; i < numWalls; ++i)
267  {
268  line >> dummy >> normal >> dummy >> position;
269  wall->addObject(normal, position * normal);
270  }
271  return wall;
272  }
273 }
274 
281 void WallHandler::readAndAddObject(std::istream& is)
282 {
283  BaseWall* o = readAndCreateObject(is);
284  unsigned int id = o->getId();
285  addObject(o);
286  getLastObject()->setId(id);
287 }
288 
292 std::string WallHandler::getName() const
293 {
294  return "WallHandler";
295 }
296 
303 {
304  const std::string fileName = getDPMBase()->getName() + "BoundingBox.vtu";
305  //logger(INFO, "% writing vtk file for bounding box: %",
306  // getDPMBase()->getTime(), fileName);
307  std::fstream file;
308  file.open(fileName.c_str(), std::ios::out);
309  if (file.fail())
310  {
312  logger(WARN, "Error in writeToFile: file could not be opened");
313  }
314  file << "<?xml version=\"1.0\"?>\n\n";
315  file << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
316  file << "<UnstructuredGrid>\n";
317  file << "<Piece NumberOfPoints=\"8\" NumberOfCells=\"1\">\n";
318  file << "<Points>\n";
319  file << " <DataArray type=\"Float32\" Name=\"Position\" NumberOfComponents=\"3\" format=\"ascii\">\n";
320  Vec3D P[2] = {getDPMBase()->getMax(), getDPMBase()->getMin()};
321  for (auto& i : P)
322  {
323  for (auto& j : P)
324  {
325  for (auto& k : P)
326  {
327  Vec3D p = Vec3D(i.X, j.Y, k.Z);
328  file << '\t' << p << '\n';
329  }
330  }
331  }
333  file << " </DataArray>\n";
334  file << "</Points>\n";
335  file << "<Cells>\n";
336  file <<
337  " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
338  file << "\t0 1 3 2 0 4 5 1 5 7 3 7 6 2 6 4\n";
339  file << " </DataArray>\n";
340  file << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
341  file <<
342  "\t16\n"; //offset into the connectivity array for the end of each cell.
343  file << " </DataArray>\n";
344  file << " <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
345  file << "\t4\n";
346  file << " </DataArray>\n";
347  file << "</Cells>\n";
348  file << "</Piece>\n";
349  file << "</UnstructuredGrid>\n";
350  file << "</VTKFile>\n";
351  file.close();
352 }
353 
362 unsigned WallHandler::readTriangleWall(std::string filename, ParticleSpecies* species, Mdouble scaleFactor, Vec3D centerOfRotation, Vec3D velocity, Vec3D angularVelocity)
363 {
364  const unsigned groupId = getNextGroupId();
365  std::string fileType = filename.substr(filename.find_last_of('.') + 1);
366 
367  //define a default triangle wall
368  TriangleWall triangleWall;
369  triangleWall.setSpecies(species);
370  triangleWall.setVelocity(velocity);
371  triangleWall.setAngularVelocity(angularVelocity);
372  triangleWall.setGroupId(groupId);
373 
374  if (helpers::lower(fileType) == "vtk")
375  {
376  //try open the input file
377  std::fstream file;
378  file.open(filename.c_str(), std::ios::in);
379  logger.assert_always(file.is_open(), "File opening failed: %", filename);
380 
381  //skip the header lines
382  std::string dummy;
383  getline(file, dummy);
384  getline(file, dummy);
385  getline(file, dummy);
386  getline(file, dummy);
387 
388  //read vertices, apply scaling
389  unsigned num;
390  file >> dummy >> num >> dummy;
391  std::vector<Vec3D> vertex;
392  vertex.reserve(num);
393  Vec3D v;
394  for (unsigned i = 0; i < num; i++)
395  {
396  file >> v.X >> v.Y >> v.Z;
397  v *= scaleFactor;
398  vertex.push_back(v);
399  }
400 
401  //read faces
402  unsigned n = getSize();
403  file >> dummy >> num >> dummy;
404  unsigned id0, id1, id2;
405  for (unsigned i = 0; i < num; i++)
406  {
407  file >> dummy >> id0 >> id1 >> id2;
408  triangleWall.setVertices(vertex[id0], vertex[id1], vertex[id2], centerOfRotation);
409  copyAndAddObject(triangleWall);
410  }
411 
412  //close file
413  file.close();
414 
415  logger(INFO, "Read in % walls from %", getSize() - n,filename);
416 
417  }
418  else if (helpers::lower(fileType) == "stl")
419  {
420 
421  BinaryReader file(filename);
422 
423  STLTriangle triangle;
424 
425  std::string header = file.readString(80);
426  unsigned numTriangles = file.readUnsignedInt(4);
427 
428  for (unsigned i = 0; i < numTriangles; i++)
429  {
430  triangle.normal.x() = file.readFloat(4);
431  triangle.normal.y() = file.readFloat(4);
432  triangle.normal.z() = file.readFloat(4);
433 
434 
435  triangle.vertex1.x() = file.readFloat(4);
436  triangle.vertex1.y() = file.readFloat(4);
437  triangle.vertex1.z() = file.readFloat(4);
438 
439  triangle.vertex2.x() = file.readFloat(4);
440  triangle.vertex2.y() = file.readFloat(4);
441  triangle.vertex2.z() = file.readFloat(4);
442 
443 
444  triangle.vertex3.x() = file.readFloat(4);
445  triangle.vertex3.y() = file.readFloat(4);
446  triangle.vertex3.z() = file.readFloat(4);
447 
448  triangle.vertex1 *= scaleFactor;
449  triangle.vertex2 *= scaleFactor;
450  triangle.vertex3 *= scaleFactor;
451 
452  //add to triangle wall
453  triangleWall.setVertices(triangle.vertex1, triangle.vertex2, triangle.vertex3, centerOfRotation);
454  copyAndAddObject(triangleWall);
455 
456  //Now ignore (read) the two dummy characters
457  file.ignoreChar(2);
458 
459  }
460 
461  logger(INFO, "Read in % walls from %", numTriangles,filename);
462 
463  }
464  else
465  {
466 
467  logger(ERROR, "File type of % must be vtk or stl");
468 
469  }
470 
471  return groupId;
472 }
473 
480 {
481  // #pragma omp parallel for //schedule(dynamic)
482  for (auto w: *this)
483  {
484  w->actionsAfterParticleGhostUpdate();
485  }
486 }
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:281
This function defines an Archimedes' screw in the z-direction from a (constant) starting point...
Definition: Screw.h:43
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here...
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:109
Vec3D getMin() const
Definition: DPMBase.h:635
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:97
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:390
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:195
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:292
Vec3D vertex1
Definition: STLTriangle.h:55
void setSpecies(const ParticleSpecies *species)
sets species of subwalls as well
void actionsAfterParticleGhostUpdate()
Calls the method actionsAfterParticleGhostUpdate of every wall in the handler.
Definition: WallHandler.cc:479
static BaseWall * createObject(const std::string &type)
Create a new wall, with the type given as a string (required for restarting).
Definition: WallHandler.cc:123
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:362
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:83
BaseWall * readAndCreateOldObject(std::istream &is)
Create a new wall, based on the information from old-style restart data.
Definition: WallHandler.cc:241
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:280
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:423
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:302
WallHandler()
Default constructor, it creates an empty WallHandler.
Definition: WallHandler.cc:51
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:641
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
MeshTriangle implements a triangle whose vertex positions are defined by three particles.
Definition: MeshTriangle.h:74