LBIBCell
 All Classes Functions Variables Friends Pages
Geometry.cpp
1 /* Copyright (c) 2013 David Sichau <mail"at"sichau"dot"eu>
2  * 2013-2015 Simon Tanaka <tanakas"at"gmx"dot"ch>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 #include <LbmLib/include/geometry/Connection.hpp>
23 #include <LbmLib/include/geometry/Geometry.hpp>
24 
25 #include <LbmLib/include/Constants.hpp>
26 #include <LbmLib/include/GlobalSimulationParameters.hpp>
27 #include <UtilLib/include/Exception.hpp>
28 #include <UtilLib/include/Log.hpp>
29 
30 #include <cmath>
31 #include <fstream>
32 #include <map>
33 #include <memory>
34 #include <string>
35 #include <vector>
36 #include <algorithm>
37 #include <cassert>
38 #include <omp.h>
39 #include <sys/stat.h>
40 
41 #include <vtkSmartPointer.h>
42 #include <vtkPolygon.h>
43 #include <vtkCellArray.h>
44 #include <vtkPolyData.h>
45 #include <vtkDoubleArray.h>
46 #include <vtkStringArray.h>
47 #include <vtkPointData.h>
48 #include <vtkCellData.h>
49 #include <vtkMultiBlockDataSet.h>
50 #include <vtkXMLMultiBlockDataWriter.h>
51 #include <vtkXMLMultiBlockDataReader.h>
52 
53 namespace LbmLib {
54 namespace geometry {
55 
56 Geometry::Geometry(const std::string& filename) : fastneighborlist_(Parameters.getSizeX(),
57  Parameters.getSizeY(),
58  (unsigned int)std::ceil(Parameters.getSizeX()/(double)MAXBINSIZE),
59  (unsigned int)std::ceil(Parameters.getSizeY()/(double)MAXBINSIZE)), isValidRangeQueryDataStructure_(0) {
60 
61  int len = strlen(filename.c_str());
62  const char *last_four = &filename.c_str()[len-4];
63 
64  if ( strcmp(last_four, ".vtm") == 0 )
65  {
66  this->loadGeometryVTK(filename);
67  }
68  else if ( strcmp(last_four, ".txt") == 0)
69  {
70  this->loadGeometryTXT(filename);
71  }
72 }
73 
75 }
76 
77 void Geometry::writeGeometry(const std::string& fileName) const {
78  std::ofstream fileStream;
79  fileStream.open(fileName);
80  if (fileStream.is_open()) {
81  fileStream << "#Nodes (id\txPos\tyPos)\n";
82  for (const auto& node : getGeometryNodes()) {
83  node.second->writeNode(&fileStream);
84  }
85  fileStream<<
86  "#Connection (nodeId1\tnodeId2\tdomainId\tbsolver\tcdesolver\t...)\n";
87  for (const auto& c : getConnections()) {
88  c->writeConnection(&fileStream);
89  }
90  } else {
91  lbm_fail("Cannot open the output file for the force solver.");
92  }
93 
94  fileStream.close();
95 }
99 void Geometry::loadGeometryTXT(const std::string& fileName) {
100  std::ifstream fileStream;
101  fileStream.open(fileName);
102  std::stringstream message;
103 
104  this->cellTypeTrackerMap_[0] = 0; // fluid default
105  message << "Loading geometry from txt file: cell type not supported; all cell types are set to 1.";
106  LOG(UtilLib::logINFO) << message.str().c_str();
107 
108  if (this->connections_.size()!=0 ||
109  this->geometryNodes_.size()!=0) {
110  lbm_fail("Only load the geometry once.");
111  }
112 
113  if (fileStream.is_open()) {
114  std::string line;
115  bool nodes = true;
116  while (std::getline(fileStream, line)) {
117  std::stringstream lineStream(line);
118  if (line.find("#Connection") != std::string::npos) {
119  nodes = false;
120  }
121  if (line.at(0) != '#') {
122  if (nodes) {
123  // we have nodes
124  unsigned int id;
125  double x, y;
126  lineStream >> id >> x >> y;
127  this->geometryNodes_[id] = std::make_shared<nodes::GeometryNode>(
128  x,
129  y,
130  id);
131  this->fastneighborlist_.addElement( // add the element also to the fastneighborlist
132  this->geometryNodes_[id]
133  );
134  } else {
135  // we have connections
136  unsigned int id1, id2, domainId;
137  std::map<std::string,
138  std::vector<std::string> > connectionType;
139  lineStream >> id1 >> id2 >> domainId;
140  this->cellTypeTrackerMap_[domainId] = 1; // JUST SET EVERYTHING TO 1
141  std::string temp1, temp2;
142  while (lineStream >> temp1 >> temp2) {
143  connectionType[temp1].push_back(temp2);
144  }
145  this->connections_.push_back(std::make_shared<Connection>(
146  geometryNodes_[id1], geometryNodes_[id2],
147  connectionType, domainId));
148 
149  // also register the connection in the nodes:
150  this->geometryNodes_[id1]->setConnection<1>(this->connections_.back());
151  this->geometryNodes_[id2]->setConnection<0>(this->connections_.back());
152  }
153  }
154  }
155  } else {
156  lbm_fail("Cannot find the geometry.txt file.");
157  }
158  fileStream.close();
159  this->isValidRangeQueryDataStructure_ = 1; // tag range query data structure as valid
160 }
161 
162 void Geometry::loadGeometryVTK(const std::string &fileName)
163 {
164  vtkSmartPointer<vtkMultiBlockDataSet> multiBDS_read =
165  vtkSmartPointer<vtkMultiBlockDataSet>::New ();
166  vtkSmartPointer<vtkXMLMultiBlockDataReader> reader =
167  vtkSmartPointer<vtkXMLMultiBlockDataReader>::New();
168  vtkSmartPointer<vtkPolyData> polygonPolyData_extract =
169  vtkSmartPointer<vtkPolyData>::New();
170  vtkSmartPointer<vtkPoints> points_extract =
171  vtkSmartPointer<vtkPoints>::New();
172  vtkSmartPointer<vtkCellArray> polygons_extract =
173  vtkSmartPointer<vtkCellArray>::New();
174  vtkSmartPointer<vtkDoubleArray> domainidentifierAttributeArray =
175  vtkSmartPointer<vtkDoubleArray>::New();
176  vtkSmartPointer<vtkDoubleArray> celltypeAttributeArray =
177  vtkSmartPointer<vtkDoubleArray>::New();
178  vtkSmartPointer<vtkDataArray> tempArray;
179  vtkSmartPointer<vtkAbstractArray> tempAbstractArray;
180  vtkSmartPointer<vtkStringArray> stringAttribute_extract =
181  vtkSmartPointer<vtkStringArray>::New();
182 
183  unsigned int blockId_polygon;
184  unsigned int blockId_count = 0;
185  double* COORD; // an array to store coordinates
186 
187  vtkIdType numPolygons;
188  vtkIdType cellLocation = 0; // the index in the cell array
189  vtkIdType numIds; // to hold the size of the cell
190  vtkIdType *pointIds; // to hold the ids in the cell
191 
192  std::map<std::string,
193  std::vector<std::string> > connectionType;
194  unsigned int id1,id2,domainId,cellType; // for the connections
195  std::string temp1,temp2;
196  vtkStdString boundarystring;
197 
198  this->cellTypeTrackerMap_[0] = 0; // fluid default
199 
200  reader->SetFileName(fileName.c_str());
201  struct stat buffer;
202  if (stat (fileName.c_str(), &buffer) == 0) {
203  reader->Update();
204  multiBDS_read->ShallowCopy(reader->GetOutput());
205 
206  for (unsigned int k=0; k<multiBDS_read->GetNumberOfBlocks(); ++k) { // loop all blocks to find the polygon block
207  polygonPolyData_extract->ShallowCopy(multiBDS_read->GetBlock(k)); // extract the block k
208  if ( strcmp(multiBDS_read->GetBlock(k)->GetClassName(),"vtkPolyData")==0 ) { // candidate blocks have to be vtkPolyData
209  polygons_extract = polygonPolyData_extract->GetPolys(); // extract the polygons
210  if (polygons_extract->GetNumberOfCells() > 0) { // this is only the right block if there are some polygons in it
211  blockId_polygon = k; // save the blockId
212  blockId_count++;
213  }
214  }
215  }
216 
217  if (blockId_count != 1) {
218  lbm_fail("more or less than one vtk polygon block found in input geometry file found.");
219  }
220 
221  polygonPolyData_extract->ShallowCopy(multiBDS_read->GetBlock(blockId_polygon)); // extract the block with the polygons
222  points_extract = polygonPolyData_extract->GetPoints(); // extract the points
223  polygons_extract = polygonPolyData_extract->GetPolys();
224  numPolygons = polygons_extract->GetNumberOfCells();
225 
226  // add the points:
227  for (int k=0; k<points_extract->GetNumberOfPoints(); ++k) {
228  COORD = points_extract->GetPoint(k);
229 
230  this->geometryNodes_[k] = std::make_shared<nodes::GeometryNode>(
231  COORD[0],
232  COORD[1],
233  k);
234  this->fastneighborlist_.addElement( // add the element also to the fastneighborlist
235  this->geometryNodes_[k]
236  );
237  }
238 
239  // extract the domain_identifier identifier flags (which are vtkPoint attributes):
240  tempArray = polygonPolyData_extract->GetPointData()->GetArray("domain_identifier");
241  if (tempArray==NULL) {
242  lbm_fail("domain_identifier array not found in vtk input file.");
243  }
244  domainidentifierAttributeArray->DeepCopy(tempArray);
245 
246  // extract the cell_type identifier flags (which are vtkPoint attributes):
247  tempArray = polygonPolyData_extract->GetPointData()->GetArray("cell_type");
248  if (tempArray==NULL) {
249  lbm_fail("cell_type array not found in vtk input file.");
250  }
251  celltypeAttributeArray->DeepCopy(tempArray);
252 
253  // extract the boundary_descriptor attributes:
254  tempAbstractArray = polygonPolyData_extract->GetPointData()->GetAbstractArray("boundarydescriptors");
255  if (tempAbstractArray==NULL) {
256  lbm_fail("boundarydescriptor array not found in vtk input file");
257  }
258  stringAttribute_extract->DeepCopy(tempAbstractArray);
259 
260  // add the connections:
261  for (vtkIdType i = 0; i < numPolygons; i++) // loop all polygons
262  {
263  polygons_extract->GetCell(cellLocation, numIds, pointIds) ;
264  cellLocation += 1 + numIds;
265 
266  assert((unsigned int)domainidentifierAttributeArray->GetSize() == (unsigned int)this->geometryNodes_.size());
267  domainId = domainidentifierAttributeArray->GetValue(pointIds[0]); // we just take the first value and do not check for consistency
268 
269  assert((unsigned int)domainidentifierAttributeArray->GetSize() == (unsigned int)this->geometryNodes_.size());
270  cellType = celltypeAttributeArray->GetValue(pointIds[0]); // we just take the first value and do not check for consistency
271  this->cellTypeTrackerMap_[domainId] = cellType; // feed the map
272 
273  for (int k=0; k<numIds-1; ++k) { // loop the points of polygon i
274  id1 = pointIds[k];
275  id2 = pointIds[k+1];
276 
277  boundarystring = stringAttribute_extract->GetValue(pointIds[k]); // get the boundary string
278  std::stringstream stringattributestringstream(boundarystring); // create a stringstream for parsing
279 
280  connectionType.clear();
281  while (stringattributestringstream >> temp1 >> temp2) { // parse pairs of strings {temp1=boundarysolver, temp2=cdesolver}
282  // check if the boundary solver have been added:
283  const std::map<std::string, double>& tempcdesolvers = Parameters.getCdeSolvers();
284 
285  bool exists = 0;
286  for (auto it : tempcdesolvers) {
287  if (temp2 == it.first) {
288  exists = 1;
289  }
290  }
291 
292  if (exists == 1) {
293  connectionType[temp1].push_back(temp2);
294  }
295  else {
296  LOG(UtilLib::logINFO) << "In the geometry file, you mention CDE solvers which do not exist in the configuration file. They're just ignored.";
297  }
298  }
299 
300  this->connections_.push_back(std::make_shared<Connection>(
301  geometryNodes_[id1], geometryNodes_[id2],
302  connectionType, domainId));
303 
304  // also register the connection in the nodes:
305  this->geometryNodes_[id1]->setConnection<1>(this->connections_.back());
306  this->geometryNodes_[id2]->setConnection<0>(this->connections_.back());
307  }
308 
309  this->connections_.push_back(std::make_shared<Connection>(
310  geometryNodes_[pointIds[numIds-1]], geometryNodes_[pointIds[0]],
311  connectionType, domainId)); // close the polygon
312 
313  // close the polygon: also register the connection in the nodes:
314  this->geometryNodes_[pointIds[numIds-1]]->setConnection<1>(this->connections_.back());
315  this->geometryNodes_[pointIds[0]]->setConnection<0>(this->connections_.back());
316  }
317  }
318  else {
319  lbm_fail("Cannot find the geometry.vtm file.");
320  }
321 }
322 
323 const std::vector<std::shared_ptr<nodes::GeometryNode> >
325  const double y,
326  const double radius) const {
327  if (this->isValidRangeQueryDataStructure_ != 1) {
329  }
330  std::vector<std::shared_ptr<nodes::GeometryNode> > queryresult;
331 
332  this->fastneighborlist_.getGeometryNodesWithinRadius(
333  queryresult,
334  x,
335  y,
336  radius);
337  return queryresult;
338 }
339 
340 const std::vector<std::shared_ptr<nodes::GeometryNode> >
342  const double y,
343  const double radius,
344  const unsigned int avoidDomainID) const
345 {
346  if (this->isValidRangeQueryDataStructure_ != 1) {
348  }
349  std::vector<std::shared_ptr<nodes::GeometryNode> > queryresult;
350 
351  this->fastneighborlist_.getGeometryNodesWithinRadiusWithAvoidance(
352  queryresult,
353  x,
354  y,
355  radius,
356  avoidDomainID);
357 
358 
359  std::vector<std::shared_ptr<nodes::GeometryNode> > temp =
360  this->getGeometryNodesWithinRadius(x,y,radius);
361 
362  return queryresult;
363 }
364 
365 std::shared_ptr<nodes::GeometryNode>
367  const double y,
368  const double radius,
369  const unsigned int avoidDomainID) const
370 {
371  if (this->isValidRangeQueryDataStructure_ != 1) {
372 #pragma omp critical
374  }
375  std::vector<std::shared_ptr<nodes::GeometryNode> > queryresult;
376  this->fastneighborlist_.getGeometryNodesWithinRadiusWithAvoidanceClosest(
377  queryresult,
378  x,
379  y,
380  radius,
381  avoidDomainID);
382 
383  if (queryresult.size() == 1) {
384  return queryresult[0];
385  }
386  else {
387  return nullptr;
388  }
389 }
390 
391 const std::vector<std::shared_ptr<Connection> >& Geometry::getConnections()
392 const {
393  return connections_;
394 }
395 
396 unsigned int Geometry::addGeometryNode(const double x,const double y) {
397  const unsigned int id = this->geometryNodes_.rbegin()->first+1; // bump new id
398  this->geometryNodes_[id] =
399  std::make_shared<nodes::GeometryNode>(
400  x,
401  y,
402  id);
403  this->fastneighborlist_.addElement( // also add the ptr to the fastneighborlist
404  this->geometryNodes_[id]
405  );
406  if (this->geometryNodes_.rbegin()->first != id) {
407  lbm_fail("Could not create and add the GeometryNode.");
408  }
409  std::stringstream message;
410  message << "GeometryNode with nodeid=" << id
411  << " added at ("<< x << "," << y << ")";
412  LOG(UtilLib::logINFO) << message.str().c_str();
413  return id;
414 }
415 
416 unsigned int Geometry::removeGeometryNode(const unsigned int nodeid)
417 {
418  try {
419  std::shared_ptr<Connection> C1 = this->geometryNodes_[nodeid]->getConnection<0>(); // incoming connection
420  std::shared_ptr<Connection> C2 = this->geometryNodes_[nodeid]->getConnection<1>(); // outgoing connection
421  std::shared_ptr<nodes::GeometryNode> N1 = C1->getGeometryNodes().first;
422  std::shared_ptr<nodes::GeometryNode> N2 = C2->getGeometryNodes().second;
423  std::map<std::string, std::vector<std::string> > descriptor = C1->getBoundaryConditionDescriptor();
424  unsigned int domainid = this->geometryNodes_[nodeid]->getDomainIdOfAdjacentConnections();
425 
426  // remove old *Connection*s:
427  this->eraseConnection(C1);
428  this->eraseConnection(C2);
429 
430  // remove old node:
431  this->fastneighborlist_.removeElement( // remove the element from the fastneighborlist
432  this->geometryNodes_[nodeid]
433  );
434  this->geometryNodes_.erase(nodeid); // remove from the primary data structure
435 
436  // add the new connection:
437  this->addConnection(N1,N2,descriptor,domainid);
438  }
439  catch (...){
440  lbm_fail("Geometry::removeGeometryNode: Could not remove the GeometryNode");
441  }
442  return 1;
443 }
444 
448 void Geometry::addConnection(std::shared_ptr<nodes::GeometryNode> p1,
449  std::shared_ptr<nodes::GeometryNode> p2,
450  const std::map<std::string, std::vector<std::string> > boundaryConditionDescriptor,
451  const unsigned int domainIdentifier) {
452 #pragma omp critical
453  {
454  this->connections_.push_back(std::make_shared<Connection>(
455  p1,
456  p2,
457  boundaryConditionDescriptor,
458  domainIdentifier));
459  // also register the connection in the nodes:
460  p1->setConnection<1>(this->connections_.back());
461  p2->setConnection<0>(this->connections_.back());
462  }
463 
464  assert(p1->getConnection<1>() != nullptr);
465  assert(p2->getConnection<0>() != nullptr);
466  LOG(UtilLib::logINFO) << "Connection added";
467 }
468 
470 {
471  std::vector<std::shared_ptr<nodes::GeometryNode> > tempvector;
472 
473  // bring into vectorform for parallelization:
474  for (auto it : this->geometryNodes_) {
475  tempvector.push_back(it.second);
476  }
477 
478  // move:
479 #pragma omp parallel for schedule(dynamic)
480  for (size_t it=0; it<tempvector.size(); ++it) {
481  tempvector[it]->move();
482  }
483  this->isValidRangeQueryDataStructure_ = 0;
484 }
485 
486 void Geometry::eraseConnection(std::shared_ptr<Connection> toDelete) {
490 #pragma omp critical
491  {
492  if (toDelete->getGeometryNodes().first->getConnection<1>()
493  == toDelete) { // only delete if it's still me (a new connection might already be subscribed)
494  toDelete->getGeometryNodes().first->setConnection<1>(nullptr);
495  }
496  if (toDelete->getGeometryNodes().second->getConnection<0>()
497  == toDelete) { // only delete if it's still me (a new connection might already be subscribed)
498  toDelete->getGeometryNodes().second->setConnection<0>(nullptr);
499  }
500  this->connections_.erase(std::remove(this->connections_.begin(),
501  this->connections_.end(),
502  toDelete),
503  this->connections_.end());
504  LOG(UtilLib::logDEBUG1) << "Connection erased.";
505  }
506 }
507 
509 {
510  try {
511  for (auto it : this->geometryNodes_) {
512  if (it.second != it.second->getConnection<0>()->getGeometryNodes().second) {
513  lbm_fail("Geometry::checkGeometryIntegrity");
514  }
515 
516  if (it.second != it.second->getConnection<1>()->getGeometryNodes().first) {
517  lbm_fail("Geometry::checkGeometryIntegrity");
518  }
519  }
520 
521  for (auto it : this->connections_) {
522  if (it != it->getGeometryNodes().first->getConnection<1>()) {
523  lbm_fail("Geometry::checkGeometryIntegrity");
524  }
525 
526  if (it != it->getGeometryNodes().second->getConnection<0>()) {
527  lbm_fail("Geometry::checkGeometryIntegrity");
528  }
529  }
530 
531  if (this->connections_.size() != this->geometryNodes_.size()) {
532  lbm_fail("Geometry::checkGeometryIntegrity: #connections != #geometrynodes");
533  }
534  }
535  catch (...) {
536  lbm_fail("Geometry::checkGeometryIntegrity: Couln't check geometry integrity.");
537  }
538  return 1;
539 }
540 
542 {
543  this->isValidRangeQueryDataStructure_ = 0;
544 }
545 
547 {
548  this->fastneighborlist_.reset(this->geometryNodes_);
549  this->isValidRangeQueryDataStructure_ = 1;
550 }
551 
552 std::map<unsigned int, unsigned int> Geometry::getCellTypeTrackerMap() const // pass by value
553 {
554  return this->cellTypeTrackerMap_;
555 }
556 
557 
558 } // end namespace
559 } // end namespace
const std::vector< std::shared_ptr< nodes::GeometryNode > > getGeometryNodesWithinRadiusWithAvoidance(const double x, const double y, const double radius, const unsigned int avoidDomainID) const
getGeometryNodesWithinRadiusWithAvoidance Range query, but only nodes with domainID different from av...
Definition: Geometry.cpp:341
unsigned int removeGeometryNode(const unsigned int nodeid)
removeGeometryNode Removes the GeometryNode with nodeid. One of the connections is removed...
Definition: Geometry.cpp:416
const std::map< unsigned int, std::shared_ptr< nodes::GeometryNode > > & getGeometryNodes() const
Getter for the geometry nodes.
Definition: Geometry.hpp:92
void moveGeometryNodes()
Geometry::moveGeometryNodes moves the *GeometryNode*s according to the local velocity field...
Definition: Geometry.cpp:469
unsigned int addGeometryNode(const double x, const double y)
addGeometryNode Add a GeometryNode. The NodeID is bumped automatically.
Definition: Geometry.cpp:396
Geometry(const std::string &filename)
Geometry constructs the geometry of the simulation.
Definition: Geometry.cpp:56
void reconstructRangeQueryDataStructure() const
reconstructRangeQueryDataStructure
Definition: Geometry.cpp:546
const std::vector< std::shared_ptr< Connection > > & getConnections() const
getConnections Getter for connections
Definition: Geometry.cpp:391
bool checkGeometryIntegrity() const
checkGeometryIntegrity
Definition: Geometry.cpp:508
~Geometry()
~Geometry Plain.
Definition: Geometry.cpp:74
void addConnection(std::shared_ptr< nodes::GeometryNode > p1, std::shared_ptr< nodes::GeometryNode > p2, const std::map< std::string, std::vector< std::string > > boundaryConditionDescriptor, const unsigned int domainIdentifier)
addConnection Add a Connection.
Definition: Geometry.cpp:448
void writeGeometry(const std::string &fileName) const
writeGeometry Writes the geometry to the file
Definition: Geometry.cpp:77
void eraseConnection(std::shared_ptr< Connection > toDelete)
eraseConnection Erase the connection.
Definition: Geometry.cpp:486
const std::vector< std::shared_ptr< nodes::GeometryNode > > getGeometryNodesWithinRadius(const double x, const double y, const double radius) const
getGeometryNodesWithinRadius Range query
Definition: Geometry.cpp:324
std::shared_ptr< nodes::GeometryNode > getGeometryNodesWithinRadiusWithAvoidanceClosest(const double x, const double y, const double radius, const unsigned int avoidDomainID) const
getGeometryNodesWithinRadiusWithAvoidanceClosest Return closest GeometryNode, but only nodes with dom...
Definition: Geometry.cpp:366
void invalidateRangeQueryDataStructure()
invalidateRangeQueryDataStructure Sets the internal flag to false.
Definition: Geometry.cpp:541
std::map< unsigned int, unsigned int > getCellTypeTrackerMap(void) const
Returns a reference to the cellTypeTrackerMap.
Definition: Geometry.cpp:552