LBIBCell
 All Classes Functions Variables Friends Pages
GeometryHandler.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/GlobalSimulationParameters.hpp>
23 #include <LbmLib/include/geometry/GeometryHandler.hpp>
24 #include <LbmLib/include/nodes/BoundaryNode.hpp>
25 #include <LbmLib/include/nodes/GeometryNode.hpp>
26 #include <LbmLib/include/nodes/PhysicalNode.hpp>
27 #include <LbmLib/include/solver/CDESolver/CDEAbstractSolver.hpp>
28 
29 #include <LbmLib/include/Constants.hpp>
30 #include <LbmLib/include/Direction.hpp>
31 
32 #include <UtilLib/include/Exception.hpp>
33 #include <UtilLib/include/Log.hpp>
34 
35 #include <boost/geometry.hpp>
36 #include <boost/geometry/geometries/point_xy.hpp>
37 #include <cassert>
38 #include <algorithm>
39 #include <cmath>
40 #include <fstream>
41 #include <iomanip>
42 #include <iostream>
43 #include <limits>
44 #include <vector>
45 #include <utility>
46 #include <map>
47 #include <omp.h>
48 
49 namespace LbmLib {
50 namespace geometry {
52  : geometry_(geometry) {
53  this->generatePhysicalGrid(); //generate PhysicalNodes and connections between them
54  this->cureLattice(); // set up IB links, *BoundaryNode*s and domainIdentifiers
55  this->cellTypeTrackerMap_ = geometry.getCellTypeTrackerMap();
56 }
57 
58 void GeometryHandler::updateDomainIdentifier() {
59 #pragma omp parallel for schedule(dynamic)
60  for (size_t y = 0; y < physicalGrid_.size(); y++) {
61  for (size_t x = 0; x < physicalGrid_[0].size(); x++) {
62  assert(physicalGrid_[y][x] != nullptr);
63  physicalGrid_[y][x]->updateDomainIdentifier();
64  }
65  }
66 }
67 
68 void GeometryHandler::updateAllDomainIdentifiers()
69 {
70 #pragma omp parallel for schedule(dynamic)
71  for (unsigned int y = 0; y < Parameters.getSizeY(); y++) { // loop y
72  unsigned int currentDomainId =
73  this->physicalGrid_[y][0]->getDomainIdentifier();
74  if (currentDomainId!=0) {
75  lbm_fail("domainID at the left boundary must be 0.");
76  }
77  for (unsigned int x = 1; x < Parameters.getSizeX(); x++) { // loop x
78  if (this->physicalGrid_[y][x]->getBoundaryNeighbour(W) != nullptr ) { // look backward
79  currentDomainId =
80  this->physicalGrid_[y][x]->getBoundaryNeighbour(W)->getDomainIdentifier();
81  }
82  this->physicalGrid_[y][x]->setDomainIdentifier(currentDomainId);
83  }
84  }
85 }
86 
88  for (auto it : physicalGrid_) {
89  for (auto i : it) {
90  delete i;
91  i = nullptr;
92  }
93  }
94 
95  for (auto b : boundaryNodes_) {
96  delete b;
97  b = nullptr;
98  }
99 }
100 
101 const std::map<unsigned int, double> GeometryHandler::computeAreas() const
102 {
103  typedef boost::geometry::model::d2::point_xy<double> point;
104  typedef boost::geometry::model::polygon< point,false,false > Polygon;
105  std::map<unsigned int,std::vector<std::shared_ptr<LbmLib::geometry::Connection> > > celldefinition;
106  std::map<unsigned int, Polygon> polygonmap;
107  std::shared_ptr<LbmLib::geometry::Connection> startC = nullptr;
108  std::shared_ptr<LbmLib::geometry::Connection> tempC = nullptr;
109  std::map<unsigned int, double> arealist;
110 
111  // step 1: create a cell definition map:
112  for (auto it : this->getGeometry().getConnections()) {
113  celldefinition[(*it).getDomainIdentifier()].push_back(it);
114  }
115 
116  // step 2: create a polygon map:
117  for (auto it : celldefinition) {
118  startC = it.second[0];
119  tempC = startC;
120  do {
121  boost::geometry::append(polygonmap[it.first], boost::geometry::make<point>(
122  tempC->getGeometryNodes().second->getXPos(),
123  tempC->getGeometryNodes().second->getYPos()));
124  tempC = tempC->getGeometryNodes().second->getConnection<1>();
125  } while(tempC != startC);
126  }
127 
128  // step 3: compute areas
129  for (auto it : polygonmap) {
130  arealist[it.first] = boost::geometry::area(it.second);
131  }
132 
133  return arealist;
134 }
135 
136 std::map<unsigned int,double> GeometryHandler::computeAccumulatedDomainConcentrations(const std::string &name) const
137 {
138  std::map<unsigned int, double> accumulatedcellconcentration;
139 
140  for (unsigned int y = 0; y < Parameters.getSizeY(); y++) { // loop y
141  for (unsigned int x = 1; x < Parameters.getSizeX(); x++) { // loop x
142  accumulatedcellconcentration[this->physicalGrid_[y][x]->getDomainIdentifier()] +=
143  this->physicalGrid_[y][x]->getCDESolverSlow(name).getC();;
144  }
145  }
146  return accumulatedcellconcentration;
147 }
148 
150 {
151  // step 1: perturb connections
152  this->perturbConnections();
153 
154  // step 2: reconnect all GeometryNodes to PhysicalNodes:
155  this->connectGeometryNodesToPhysicalNodes();
156 
157  // step 3: delete all BoundaryNodes:
158  for (auto b : this->boundaryNodes_) {
159  b->getPhysicalNeighbour()->resetBoundaryNodes();
160  delete b;
161  b = nullptr;
162  }
163  this->boundaryNodes_.clear();
164 
165  // step 4: re-generate BoundaryNodes:
166  this->generateBoundaryNodes();
167 
168  // step 5: update all domain identifiers of the *PhysicalNode*s
169  this->updateAllDomainIdentifiers();
170 }
171 
172 unsigned int GeometryHandler::createGeometryNode(const double xpos, const double ypos)
173 {
174  return const_cast<geometry::Geometry&>(this->geometry_).addGeometryNode(xpos,ypos);
175 }
176 
177 void GeometryHandler::createConnection(const std::shared_ptr<nodes::GeometryNode> p1,
178  const std::shared_ptr<nodes::GeometryNode> p2,
179  const std::map<std::string, std::vector<std::string> > boundaryconditiondescriptor,
180  const unsigned int domainidentifier)
181 {
182  const_cast<geometry::Geometry&>(this->geometry_).addConnection(p1,
183  p2,
184  boundaryconditiondescriptor,
185  domainidentifier);
186 }
187 
188 void GeometryHandler::eraseConnection(std::shared_ptr<Connection> toErase)
189 {
190  const_cast<geometry::Geometry&>(this->geometry_).eraseConnection(toErase);
191 }
192 
193 const std::shared_ptr<nodes::GeometryNode> GeometryHandler::returnGeometryNode(const unsigned int nodeID) const
194 {
195  return this->geometry_.getGeometryNodes().at(nodeID);
196 }
197 
199 {
200  unsigned int myID;
201  std::array<Direction, 4> dir {{N,S,E,W}};
202 
203  for (unsigned int y = 0; y < Parameters.getSizeY(); y++) { // loop y
204  for (unsigned int x = 0; x < Parameters.getSizeX(); x++) { // loop x
205  myID = this->physicalGrid_[y][x]->getDomainIdentifier();
206 
207  // check if domainID's are consistent if neighbor is PhysicalNode:
208  for (auto d : dir) {
209  if (this->physicalGrid_[y][x]->getBoundaryNeighbour(d) == nullptr) {
210  if (myID != this->physicalGrid_[y][x]->getPhysicalNeighbour(d)->getDomainIdentifier()) {
211  std::stringstream message;
212  message << "Grid integrity not given (domainID jump to PhysicalNode neighbor): ";
213  message << "time=" << Parameters.getCurrentIteration() << "; ";
214  message << "position=(" << x << "," << y << "); ";
215  message << "my domainID=" << myID << "; ";
216  message << "neighbor domainID=" << this->physicalGrid_[y][x]->getPhysicalNeighbour(d)->getDomainIdentifier() << "; ";
217  message << "direction=" << d;
218  LOG(UtilLib::logINFO) << message.str().c_str();
219  lbm_fail(message.str().c_str());
220  }
221  }
222  }
223 
224  // check if domainID's are consistent if neighbor is BoundaryNode:
225  for (auto d : dir) {
226  if (this->physicalGrid_[y][x]->getBoundaryNeighbour(d) != nullptr) {
227  if (myID != this->physicalGrid_[y][x]->getBoundaryNeighbour(d)->getDomainIdentifier()) {
228  std::stringstream message;
229  message << "Grid integrity not given (domainID jump to BoundaryNode neighbor): ";
230  message << "time=" << Parameters.getCurrentIteration() << "; ";
231  message << "position=(" << x << "," << y << "); ";
232  message << "my domainID=" << myID << "; ";
233  message << "neighbor domainID=" << this->physicalGrid_[y][x]->getBoundaryNeighbour(d)->getDomainIdentifier() << "; ";
234  message << "direction=" << d;
235  LOG(UtilLib::logINFO) << message.str().c_str();
236  lbm_fail(message.str().c_str());
237  }
238  }
239  }
240  }
241  }
242 }
243 
245 {
246  std::array<Direction, 4> dir {{N,S,E,W}};
247 
248  for (unsigned int y = 0; y < Parameters.getSizeY(); y++) { // loop y
249  for (unsigned int x = 0; x < Parameters.getSizeX(); x++) { // loop x
250  for (auto d : dir) {
251  if (this->physicalGrid_[y][x]->getBoundaryNeighbour(d) != nullptr) {
252  if (this->physicalGrid_[y][x]->getPhysicalNeighbour(d)->getBoundaryNeighbour(getInverseDirection(d)) == nullptr) {
253  std::stringstream message;
254  message << "BoundaryNode integrity not given: ";
255  message << "time=" << Parameters.getCurrentIteration() << "; ";
256  message << "PhysicalNode (" << x << "," << y << "); ";
257  message << "direction " << d << "; ";
258  LOG(UtilLib::logINFO) << message.str().c_str();
259  lbm_fail(message.str().c_str());
260  }
261  }
262  }
263  }
264  }
265 }
266 
267 void GeometryHandler::copyCellTypeToPhysicalNodes(std::map<unsigned int,unsigned int> &celltrackermap)
268 {
269  unsigned int id;
270 
271 #pragma omp parallel for schedule(dynamic) private(id)
272  for (size_t y = 0; y < physicalGrid_.size(); y++) {
273  for (size_t x = 0; x < physicalGrid_[0].size(); x++) {
274  assert(physicalGrid_[y][x] != nullptr);
275  id = this->physicalGrid_[y][x]->getDomainIdentifier();
276 
277  //check if id is a valid key in celltrackermap:
278  if (celltrackermap.find(id) == celltrackermap.end() )
279  {
280  // key 2 doesn't exist
281 #pragma omp critical
282  {
283  celltrackermap[id] = 1;
284  std::stringstream message;
285  message << "GeometryHandler::copyCellTypeToPhysicalNodes(): Could not find domainID="
286  << id <<"; added it and set to cellType=1. " ;
287 
288  message << "The celltrackermap reads: [domainID/cellType]: ";
289  for (auto it : celltrackermap) {
290  message << "[" << it.first << "/" << it.second << "] ";
291  }
292  LOG(UtilLib::logINFO) << message.str().c_str();
293  }
294  }
295 
296  this->physicalGrid_[y][x]->setCellType(
297  celltrackermap[id]
298  );
299  }
300  }
301 }
302 
303 void GeometryHandler::copyCellTypeToPhysicalNodes(unsigned int domainidentifier, unsigned int celltype)
304 {
305 #pragma omp parallel for schedule(dynamic)
306  for (size_t y = 0; y < physicalGrid_.size(); y++) {
307  for (size_t x = 0; x < physicalGrid_[0].size(); x++) {
308  assert(physicalGrid_[y][x] != nullptr);
309  if (this->physicalGrid_[y][x]->getDomainIdentifier() == domainidentifier) {
310  this->physicalGrid_[y][x]->setCellType(celltype);
311  }
312  }
313  }
314 }
315 
316 std::map<unsigned int,unsigned int>& GeometryHandler::getCellTypeTrackerMap()
317 {
318  return this->cellTypeTrackerMap_;
319 }
320 
322 {
323  return this->geometry_.checkGeometryIntegrity();
324 }
325 
326 void GeometryHandler::perturbConnections() {
327  std::map<unsigned int,std::shared_ptr<LbmLib::geometry::Connection> > celldefinitionmap;
328  std::vector<std::shared_ptr<LbmLib::geometry::Connection> > celldefinitionvector;
329  std::shared_ptr<LbmLib::geometry::Connection> startC = nullptr;
330  std::shared_ptr<LbmLib::geometry::Connection> tempC = nullptr;
331 
332  // step 1: create a cell definition map with only one connection per domainIdentifier:
333  for (auto it : this->getGeometry().getConnections()) {
334  if (celldefinitionmap.find((*it).getDomainIdentifier()) == celldefinitionmap.end()) { // check if not existing yet
335  celldefinitionmap[(*it).getDomainIdentifier()] = it; // if not yet existing, add
336  }
337  }
338 
339  // step 2: cast everything into a vector for openmp looping:
340  for (auto it : celldefinitionmap) {
341  celldefinitionvector.push_back(it.second);
342  }
343 
344  //step 3: loop all cells and perturb. each cell is perturbed sequentially.
345 #pragma omp parallel for schedule(dynamic) private(startC,tempC)
346  for (size_t it=0;
347  it<celldefinitionvector.size();
348  ++it) {
349  startC = celldefinitionvector[it];
350  tempC = startC;
351  do {
352  tempC->perturbConnection();
353  tempC = tempC->getGeometryNodes().second->getConnection<1>();
354  } while(tempC != startC);
355  }
356 }
357 
359  // step 1: move the GeometryNodes:
360  const_cast<geometry::Geometry&>(this->geometry_).moveGeometryNodes();
361  this->perturbConnections();
362 
363  // step 2: delete all BoundaryNodes:
364  for (auto b : this->boundaryNodes_) {
365  b->getPhysicalNeighbour()->resetBoundaryNodes();
366  delete b;
367  b = nullptr;
368  }
369  this->boundaryNodes_.clear();
370 
371  // step 3: re-generate BoundaryNodes:
372  this->generateBoundaryNodes();
373 
374  // step 4: reconnect GeometryNodes to PhysicalNodes:
375  this->connectGeometryNodesToPhysicalNodes();
376 
377  // step 5: calls updateDomainIdentifier() of PhysicalNode:
378  this->updateDomainIdentifier(); // force CDE solver reinit
379  this->updateAllDomainIdentifiers();
380 
381  // step 6: update cell types
382  this->copyCellTypeToPhysicalNodes(this->cellTypeTrackerMap_);
383 }
384 
386  // copy the connection vector in order not to interfer with modifications on the original:
387  std::vector<std::shared_ptr<Connection> > concopy(this->geometry_.getConnections());
388  unsigned int counter = 0;
389 
390  for (auto c = concopy.begin();
391  c != concopy.end();
392  c++) {
393  if ((*c)->getLength()>MAXLENGTH) {
394  // step 1: add the new GeometryNode
395  const double x1 = (*c)->getGeometryNodes().first->getXPos();
396  const double y1 = (*c)->getGeometryNodes().first->getYPos();
397  const double x2 = (*c)->getGeometryNodes().second->getXPos();
398  const double y2 = (*c)->getGeometryNodes().second->getYPos();
399  const unsigned int newnodeID =
400  this->createGeometryNode((x1+x2)/2,(y1+y2)/2);
401 
402  const std::shared_ptr<nodes::GeometryNode> newnode = // get pointer to the newly created GeometryNode
403  this->returnGeometryNode(newnodeID);
404 
405  // step 2: get the signature of the old connection
406  std::pair<std::shared_ptr<nodes::GeometryNode> const,
407  std::shared_ptr<nodes::GeometryNode> const> adjacentnodes = (*c)->getGeometryNodes();
408  std::map<std::string, std::vector<std::string> > descriptor = (*c)->getBoundaryConditionDescriptor();
409  const unsigned int domainID = (*c)->getDomainIdentifier();
410 
411  // step 3: delete the old connection
412  this->eraseConnection(*c);
413 
414  // step 4: add two new connections
415  this->createConnection(adjacentnodes.first,
416  newnode,
417  descriptor,
418  domainID);
419  this->createConnection(newnode,
420  adjacentnodes.second,
421  descriptor,
422  domainID);
423  counter++;
424  }
425  }
426 
427  // step 5: reconnect GeometryNodes to PhysicalNodes:
428  this->connectGeometryNodesToPhysicalNodes();
429 
430  return counter;
431 }
432 
434 {
435  double length;
436  Field<double> P1;
437  Field<double> P2;
438 
439  // loop all *GeometryNode*s
440  for (auto it = this->getGeometry().getGeometryNodes().begin();
441  it!=this->getGeometry().getGeometryNodes().end();
442  ) {
443 
444  // determine length without me
445  P1 = (*it).second->getConnection<0>()->getGeometryNodes().first->getPos();
446  P2 = (*it).second->getConnection<1>()->getGeometryNodes().second->getPos();
447  length = std::sqrt( (P2.x-P1.x)*(P2.x-P1.x) + (P2.y-P1.y)*(P2.y-P1.y) );
448 
449  if (length < MAXLENGTH) {
450  std::stringstream message;
451  message << "GeometryHandler::coarsenBoundary(): "
452  << "removed GeometryNode=" << (*it).first <<"; "
453  << "length=" << length;
454  const_cast<geometry::Geometry&>(this->getGeometry()).removeGeometryNode((*it++).first);
455  LOG(UtilLib::logINFO) << message.str().c_str();
456  }
457  else {
458  ++it;
459  }
460  }
461 }
462 
463 void GeometryHandler::generatePhysicalGrid() {
464  for (unsigned int y = 0; y < Parameters.getSizeY(); y++) {
465  std::vector<nodes::PhysicalNode*> temp;
466  for (unsigned int x = 0; x < Parameters.getSizeX(); x++) {
467  temp.push_back(new nodes::PhysicalNode(x, y));
468  }
469  physicalGrid_.push_back(temp);
470  }
471 
472  this->makePhysicalGridConnections();
473  this->makePeriodicBoundary();
474 }
475 
476 void GeometryHandler::makePhysicalGridConnections() {
477  // make the connections.
478 
479  for (auto it : physicalGrid_) {
480  for (auto i : it) {
481  unsigned int x = i->getXPos();
482  unsigned int y = i->getYPos();
483  // not most left wall
484  if (x != Parameters.getSizeX() - 1) {
485  i->setPhysicalNeighbour(physicalGrid_[y][x + 1], E);
486  }
487  // not NE corner
488  if ((x != Parameters.getSizeX() - 1) &&
489  (y != Parameters.getSizeY() - 1) ) {
490  i->setPhysicalNeighbour(physicalGrid_[y + 1][x + 1], NE);
491  }
492  // not top line
493  if (y != Parameters.getSizeY() - 1) {
494  i->setPhysicalNeighbour(physicalGrid_[y + 1][x], N);
495  }
496  // not NW corner
497  if ((x != 0) && (y != Parameters.getSizeY() - 1)) {
498  i->setPhysicalNeighbour(physicalGrid_[y + 1][x - 1], NW);
499  }
500  // not right wall
501  if (x != 0) {
502  i->setPhysicalNeighbour(physicalGrid_[y][x - 1], W);
503  }
504  // not SW corner
505  if ((x != 0) && (y != 0)) {
506  i->setPhysicalNeighbour(physicalGrid_[y - 1][x - 1], SW);
507  }
508  // not bottom line
509  if (y != 0) {
510  i->setPhysicalNeighbour(physicalGrid_[y - 1][x], S);
511  }
512  // not SE corner
513  if ((x != Parameters.getSizeX() - 1) && (y != 0)) {
514  i->setPhysicalNeighbour(physicalGrid_[y - 1][x + 1], SE);
515  }
516  }
517  }
518 }
519 
520 void GeometryHandler::makePeriodicBoundary() {
521  // make the periodic boundary condition
522  for (auto it : physicalGrid_) {
523  for (auto i : it) {
524  unsigned int x = i->getXPos();
525  unsigned int y = i->getYPos();
526 
527  if (x == Parameters.getSizeX() - 1) {
528  i->setPhysicalNeighbour(physicalGrid_[y][0], E); // set east direction
529  if (y != 0) {
530  i->setPhysicalNeighbour(physicalGrid_[y - 1][0], SE); // set south east direction
531  } else {
532  i->setPhysicalNeighbour(physicalGrid_[Parameters.getSizeY()
533  - 1][0], SE); // its the SE edge
534  }
535  if (y != Parameters.getSizeY() - 1) {
536  i->setPhysicalNeighbour(physicalGrid_[y + 1][0], NE); // set north east direction
537  } else {
538  i->setPhysicalNeighbour(physicalGrid_[0][0], NE); // its the NE edge
539  }
540  }
541 
542  if (y == Parameters.getSizeY() - 1) {
543  i->setPhysicalNeighbour(physicalGrid_[0][x], N); // set north direction
544  if (x != Parameters.getSizeX() - 1) {
545  i->setPhysicalNeighbour(physicalGrid_[0][x + 1], NE); // set north east direction
546  } // edge already setted
547  if (x != 0) {
548  i->setPhysicalNeighbour(physicalGrid_[0][x - 1], NW); // set north west direction
549  } // edge already setted
550  }
551 
552  if (x == 0) {
553  if (y != 0) {
554  i->setPhysicalNeighbour(physicalGrid_[y -
555  1][Parameters.getSizeX()
556  - 1], SW); // set south west direction
557  } else {
558  i->setPhysicalNeighbour(physicalGrid_[Parameters.getSizeY()
559  - 1][Parameters.
560  getSizeX() - 1],
561  SW); // its the SW edge
562  }
563  if (y != Parameters.getSizeY() - 1) {
564  i->setPhysicalNeighbour(physicalGrid_[y + 1][Parameters.
565  getSizeX() -
566  1], NW); // set north west direction
567  } else {
568  i->setPhysicalNeighbour(physicalGrid_[0][Parameters.
569  getSizeX() - 1],
570  NW); // its the NW edge
571  }
572  i->setPhysicalNeighbour(physicalGrid_[y][Parameters.getSizeX()
573  - 1], W); // set west direction
574  }
575  if (y == 0) {
576  if (x != 0) {
577  i->setPhysicalNeighbour(physicalGrid_[Parameters.getSizeY()
578  - 1][x - 1], SW); // set south west direction
579  } // edge already setted
580  if (x != Parameters.getSizeX() - 1) {
581  i->setPhysicalNeighbour(physicalGrid_[Parameters.getSizeY()
582  - 1][x + 1], SE); // set south east direction
583  } // edge already setted
584  i->setPhysicalNeighbour(physicalGrid_[Parameters.getSizeY() -
585  1][x], S); // set south direction
586  }
587  }
588  }
589 }
590 
591 void GeometryHandler::connectGeometryNodesToPhysicalNodes() {
592  typedef std::map<unsigned int,std::shared_ptr<nodes::GeometryNode> >::const_iterator MapIterator;
593  std::vector<MapIterator> helper_vector;
594 
595  // create a helper vector for parallelization:
596  for (MapIterator it=this->geometry_.getGeometryNodes().begin();
597  it!=this->geometry_.getGeometryNodes().end();
598  ++it) {
599  helper_vector.push_back(it);
600  }
601 
602 #pragma omp parallel for schedule(static)
603  for (size_t it=0; it<helper_vector.size(); ++it) {
604  this->connectGeometryNodesToPhysicalNodes(helper_vector[it]->second);
605  }
606 }
607 
608 void GeometryHandler::connectGeometryNodesToPhysicalNodes(
609  std::shared_ptr<nodes::GeometryNode> pt) {
610  if (!pt->isUpdateNeeded())
611  return;
612 
613  double minX = pt->getXPos() - 2.0;
614  double maxX = pt->getXPos() + 2.0;
615  double minY = pt->getYPos() - 2.0;
616  double maxY = pt->getYPos() + 2.0;
617 
618  if (minX < 0) {
619  lbm_fail(
620  "geometry point moved too close to the west boundary");
621  }
622 
623  if (minY < 0) {
624  lbm_fail(
625  "geometry point moved too close to the south boundary");
626  }
627 
628  if (maxX > Parameters.getSizeX()) {
629  lbm_fail(
630  "geometry point moved too close to the east boundary");
631  }
632 
633  if (maxY > Parameters.getSizeY()) {
634  lbm_fail(
635  "geometry point moved too close to the north boundary");
636  }
637 
638 
639  for (int x = std::ceil(minX); x <= std::floor(maxX); x++) {
640  for (int y = std::ceil(minY); y <= std::floor(maxY); y++) {
641  pt->addPhysicalNode(this->physicalGrid_[y][x], (x * 4 + y) % 16);
642  }
643  }
644 }
645 
646 void GeometryHandler::generateBoundaryNodes() {
647  std::vector<std::shared_ptr<Connection> > helper_vector =
648  this->geometry_.getConnections();
649 
653 //#pragma omp parallel for schedule(static)
654  for (size_t it=0;
655  it<helper_vector.size();
656  ++it) {
657  helper_vector[it]->generateBoundaryNodes(this->physicalGrid_, this->boundaryNodes_);
658  }
659 }
660 } // end namespace
661 } // end namespace
void copyCellTypeToPhysicalNodes(std::map< unsigned int, unsigned int > &celltrackermap)
update the celltypes of all *PhysicalNode*s with domainid
void eraseConnection(std::shared_ptr< Connection > toErase)
Erases the Connection.
void checkLatticeIntegrity()
Check lattice integrity.
const std::shared_ptr< nodes::GeometryNode > returnGeometryNode(const unsigned int nodeID) const
returnGeometryNode
const std::map< unsigned int, std::shared_ptr< nodes::GeometryNode > > & getGeometryNodes() const
Getter for the geometry nodes.
Definition: Geometry.hpp:92
~GeometryHandler()
~GeometryHandler Destroyes all nodes.
std::map< unsigned int, double > computeAccumulatedDomainConcentrations(const std::string &name) const
Compute the accumulated concentrations of species name in all domains.
bool checkGeometryIntegrity(void) const
checkGeometryIntegrity
class representing a physical node
void createConnection(std::shared_ptr< nodes::GeometryNode > const p1, std::shared_ptr< nodes::GeometryNode > const p2, const std::map< std::string, std::vector< std::string > > boundaryconditiondescriptor, const unsigned int domainidentifier)
Create a new connection.
T x
x the value in x direction
Definition: Field.hpp:50
void coarsenBoundary()
If *Connection*s are too short, a GeometryNode is remove.
void moveLattice()
moveLattcie Updates the Lattice after the Geometric Points have been moved
const Geometry & getGeometry() const
getter for the geometry
void cureLattice()
Cure the Lattice: update *BoundaryNode*s, DomainIdentifier, and IB connections.
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
const std::map< unsigned int, double > computeAreas() const
Compute the areas of the domains by using the domainIdentifiers.
unsigned int remeshBoundary()
If a Connection is too long, a GeometryNode is added and linked.
void checkBoundaryNodeIntegrity()
checkBoundaryNodeIntegrity Checks the integrity of the boundary node pairs.
unsigned int createGeometryNode(const double xpos, const double ypos)
Add a new GeometryNode.
GeometryHandler(const Geometry &geometry)
GeometryHandler Constructs the simulation grid.
class representing the external geometry
Definition: Geometry.hpp:68
std::map< unsigned int, unsigned int > & getCellTypeTrackerMap(void)
Returns a reference to the cellTypeTrackerMap.
T y
y the value in y direction
Definition: Field.hpp:54
std::map< unsigned int, unsigned int > getCellTypeTrackerMap(void) const
Returns a reference to the cellTypeTrackerMap.
Definition: Geometry.cpp:552