meshGraph.hh

Go to the documentation of this file.
1 #ifndef meshGraph_hh
2 #define meshGraph_hh
3 
4 #include "hp2D.hh"
5 #include "toolbox.hh"
6 
7 //evtl hp2D
8 namespace concepts{
9 
10 
11 
12 
13 class MacroElementNode;
14 
16 
17 public:
19  node1_ = node1;
20  node2_ = node2;
21  }
22 
23  //returns the requested node
24  // i = 0 first, else the second
26  return i ? node2_ : node1_;
27  }
28 
29 // Vertex* getOrigin() {return origin;}
30 // Vertex* getDestination() {return destination;}
31 
32 private:
35 };
36 
37 //TODO: Ein macroElementNode kennt seine mögliche nachbaranzahl
38 // viereck = max 4, dreieck = max 3, usw
39 
41 
42 public:
43 
45 
47  content_.push_back(quad);
48  };
49 
50  //sets the pointer to edge in given direction :
51  // direction = 0 south
52  // = 1 east
53  // = 2 north
54  // = 3 west
55  //
56  // position of the node in the edge
57  void setEdge(uint direction, MeshGraph2_Edge* edge, uint pos){
58  switch(direction){
59  case 0 : south_ = edge; s_p = pos; break;
60  case 1 : east_ = edge; e_p = pos; break;
61  case 2 : north_ = edge; n_p = pos; break;
62  case 3 : west_ = edge; w_p = pos; break;
63  default:
64  throw conceptsException(concepts::MissingFeature("Only 4 direction supported."));
65  break;
66  }
67  }
68 
69  void addContent(const hp2D::Quad<Real>* quad){
70  content_.push_back(quad);
71  }
72 
73  const uint nEdges() const {
74  return bool(south_) + bool(east_) + bool(north_) + bool(west_);
75  }
76 
77 
78  const hp2D::Quad<Real>* get() const{
79  if(content_.size() == 1)
80  return content_[0];
81  else{
82  DEBUGL(1, "content_ "<< content_);
83  throw conceptsException(concepts::MissingFeature("Only one content supported."));
84  }
85  }
86 
87  //returns pointer to requested neighbour //TODO generalize with "sides of node element
88  //direction :south = 0 east = 1 north = 2 west = 3
89  const MacroElementNode* neighbour(ushort direction) const{
90  switch (direction) {
91  case 0:
92  if (south_)
93  return south_->node((s_p + 1) % 2);
94  else
95  return 0;
96  break;
97  case 1:
98  if (east_)
99  return east_->node((e_p + 1) % 2);
100  else
101  return 0;
102  break;
103  case 2:
104  if (north_)
105  return north_->node((n_p + 1) % 2);
106  else
107  return 0;
108  break;
109  case 3:
110  if (west_)
111  return west_->node((w_p + 1) % 2);
112  else
113  return 0;
114  break;
115  default:
116  throw conceptsException(concepts::MissingFeature("Only 4 direction supported."));
117  break;
118  }
119  } // neighbour
120 
121 protected:
122  virtual std::ostream& info(std::ostream& os) const {
123  os << "MacroElementNode[ #content = " << content_.size() << std::endl;
124  if (content_.size() == 1){
125  os << " has south : " << ((south_) ? "true" : "false" )<< std::endl
126  << " has east : " << ((east_) ? "true" : "false" )<< std::endl
127  << " has north : " << ((north_) ? "true" : "false") << std::endl
128  << " has west : " << ((west_) ? "true" : "false") << std::endl;
129  }
130  if(content_.size()==1){
131  os << "content key = "<< content_[0]->support().key() << std::endl;
132  if(south_)
133  os << "south key = " << neighbour(0)->get()->support().key() << std::endl;
134  if(east_)
135  os << "east key = " << neighbour(1)->get()->support().key() << std::endl;
136  if(north_)
137  os << "north key = " << neighbour(2)->get()->support().key() << std::endl;
138  if(west_)
139  os << "west key = " << neighbour(3)->get()->support().key() << std::endl;
140  }
141  return os << "]";
142  }
143 
144 private:
145 
147  //position of the node on the Edge
148  uint s_p, e_p, n_p, w_p;
149 
150  //information holded in that MacroNode, i.e. all Quads in it
152 
153 
154 };
155 
156 
157 
158 //a bidirected graph to walk trough a mesh possible having hanging nodes
159 //therefore socallded MacroElementNodes are introduced
160 
161 // only half splitting
162 // _____
163 // | | |
164 // ___|__|__|__ ...
165 // | | |__|..: bisection in both direction
166 // |___|_____|__|..:
167 // //////
168 // BDN
169 //
170 
171 // definition
172 // regular graph : only for same refinement level neighbours
173 // irregular graph :
174 
175 
176 
177 
178 class MeshGraph2 : public OutputOperator{
179 
180 public:
181 
183 
184  MeshGraph2(const concepts::SpaceOnCells<Real>& spc, bool regular = true) : regular_(regular){
185 
186  //maps from topology edge key to underlying quads
188  // O(1) access to quads later to avoid dynamic cast
190 
191  //build edge topology map;
192  std::auto_ptr<concepts::SpaceOnCells<Real>::Scanner> sc(spc.scan());
193  while (*sc) {
194  concepts::ElementWithCell<Real>& elm = (*sc)++;
195  //TODO: what quad?
196  const hp2D::Quad<Real>* quad = dynamic_cast<const hp2D::Quad<Real>*> (&elm);
197  //element must be q quad
199 
200  quads[quad->support().key()] = quad;
201 
202  //Build information about underlying elements
203  const concepts::Quad& cntr = quad->support();
204  for (uint i = 0; i < 4; ++i) {
205  const concepts::Edge& edge = *cntr.edge(i);
206  uelm[edge.key()].push_back(UnderlyingElement(quad, i));
207  }
208  }//while
209 
210 
211  //TODO: USE THE FOLLOWING CONCEPT OF BOUNDARY CONDITIONS
212  //Space with a boundary condition
213  const hp2D::hpAdaptiveSpace<Real>* bcSpace = dynamic_cast<const hp2D::hpAdaptiveSpace<Real>* >(&spc);
214  if(!bcSpace)
215  throw conceptsException(concepts::MissingFeature("Just Spaces with boundary conditions are allowed"));
216 
217  const BoundaryConditions* bc = bcSpace->helper().bc();
218 
219 
220 
221  //Build the Graph
222 
223  //build a regular graph, i.e.
224  // - neighboured MacroElementNodes have only one content size one
225  // - its content has same level in h-refinement sense
226  if(regular){
227 
228  //iterate over all Quads and Build the Node contents
229  concepts::HashMap<const hp2D::Quad<Real>*>::const_iterator qIter = quads.begin();
230  for( ; qIter != quads.end(); ++qIter){
231  uint K = qIter->first;
232  nodes_[K] = new MacroElementNode(qIter->second);
233  }
234 
236  iter = uelm.begin();
237  for( ; iter != uelm.end(); ++iter){
238  if(iter->second.size() == 2){
239  uint E = iter->first;
240  const hp2D::Quad<Real>* quad_1 =
241  dynamic_cast<const hp2D::Quad<Real>*> (iter->second[0].elm);
242  const hp2D::Quad<Real>* quad_2 =
243  dynamic_cast<const hp2D::Quad<Real>*> (iter->second[1].elm);
244  uint K1 = quad_1->support().key();
245  uint K2 = quad_2->support().key();
246  //build a graph Edge between both Nodes
247  edges_[E] = new MeshGraph2_Edge(nodes_[K1],nodes_[K2]);
248 
249  //add the Edge its Nodes
250  nodes_[K1]->setEdge(iter->second[0].k, edges_[E], 0);
251  nodes_[K2]->setEdge(iter->second[1].k, edges_[E], 1);
252  }
253  }
254 
255 
256 
257  }
258  //TODO : build irregular graph, i.e.
259  // - neighboured MacroElementNodes are MacroElements consisting of
260  // quads forming the Edge Support
261  // - neighboured refinement level may differs
262  else{
263  throw conceptsException(concepts::MissingFeature("Irregular Mapping not implemented"));
264  }
265  }
266 
267 
268  virtual ~MeshGraph2(){
269 
271  HashMap<MeshGraph2_Edge* >::iterator edgeIter = edges_.begin();
272  //delete allocated nodes
273  for( ; nodeIter != nodes_.end(); ++nodeIter){
274  if( nodeIter->second ){
275  delete nodeIter->second;
276  nodeIter->second = 0;
277  }
278  }
279  //delete allocated edges
280  for( ; edgeIter != edges_.end(); ++edgeIter){
281  if(edgeIter->second){
282  delete edgeIter->second;
283  edgeIter->second = 0;
284  }
285  }
286  }
287 
288  //returns the requested node (representation of Cell with key K
289  const MacroElementNode* getNode(const uint K) const{
291  if( (iter = nodes_.find(K)) != nodes_.end() )
292  return iter->second;
293  return 0;
294  }
295 
296 
297 
298 
299 
300 protected:
301  virtual std::ostream& info(std::ostream& os) const {
302  os << "MeshGraph2[ #Nodes = " << nodes_.size() << " #Edges = " << edges_.size()
303  << " regular = "<< regular_ << std::endl;
304 
306  for( ; nodeIter != nodes_.end(); ++nodeIter)
307  os << *(nodeIter->second) << std::endl;
308 
309  return os;
310 
311  }
312 
313 private:
314  bool regular_;
315 
316  //HashMap<MacroElementNode> map_;
317 
318  //the edge number here corresponds with the coarsest adjacent topological
319  // edge that is in the space, i.e. hanging edges
320  //TODO: change this to a PList, as no direct contact as for nodes will be needed?!
322  //the node corresponds numerical with its topological key
324 
325 };
326 
327 
328 } //namespace
329 
330 
331 #endif // meshGraph_hh
MeshGraph2_Edge * north_
Definition: meshGraph.hh:146
virtual ~MeshGraph2()
Definition: meshGraph.hh:268
HashMap< MacroElementNode * > nodes_
Definition: meshGraph.hh:323
#define conceptsException(exc)
Prepares an exception for throwing.
Definition: exceptions.hh:344
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: meshGraph.hh:301
concepts::ElementAndFacette< hp2D::Element< Real > > UnderlyingElement
Definition: meshGraph.hh:182
MeshGraph2_Edge(MacroElementNode *node1, MacroElementNode *node2)
Definition: meshGraph.hh:18
A quadrilateral in the topology.
Definition: topology.hh:272
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: meshGraph.hh:122
#define conceptsAssert(cond, exc)
Assert that a certain condition is fulfilled.
Definition: exceptions.hh:394
MacroElementNode * node2_
Definition: meshGraph.hh:34
#define DEBUGL(doit, msg)
concepts::Sequence< const hp2D::Quad< Real > * > content_
Definition: meshGraph.hh:151
MacroElementNode * node1_
Definition: meshGraph.hh:33
Edge * edge(uint i) const
Returns a 1D component: edge.
Definition: topology.hh:316
const MacroElementNode * neighbour(ushort direction) const
Definition: meshGraph.hh:89
const concepts::SubspaceHelper< F, SpacePreBuilder > & helper() const
MacroElementNode * node(ushort i)
Definition: meshGraph.hh:25
Exception class for assertions.
Definition: exceptions.hh:258
const MacroElementNode * getNode(const uint K) const
Definition: meshGraph.hh:289
const Key & key() const
Returns the key of the connector.
Definition: connector.hh:105
Sequence with operations, output operator, and method of the particular element types.
Definition: sequence.hh:39
MeshGraph2_Edge * east_
Definition: meshGraph.hh:146
MeshGraph2_Edge * west_
Definition: meshGraph.hh:146
const hp2D::Quad< Real > * get() const
Definition: meshGraph.hh:78
HashMap< MeshGraph2_Edge * > edges_
Definition: meshGraph.hh:321
void addContent(const hp2D::Quad< Real > *quad)
Definition: meshGraph.hh:69
void setEdge(uint direction, MeshGraph2_Edge *edge, uint pos)
Definition: meshGraph.hh:57
unsigned short ushort
Abbreviation for unsigned short.
Definition: typedefs.hh:48
Exception class to express a missing feature.
Definition: exceptions.hh:206
MeshGraph2(const concepts::SpaceOnCells< Real > &spc, bool regular=true)
Definition: meshGraph.hh:184
virtual Scanner * scan() const =0
Returns a scanner to iterate over the elements of the space.
const uint nEdges() const
Definition: meshGraph.hh:73
MeshGraph2_Edge * south_
Definition: meshGraph.hh:146
An edge in the topology.
Definition: topology.hh:73
MacroElementNode(const hp2D::Quad< Real > *quad)
Definition: meshGraph.hh:46
Class providing an output operator.
Container for an element and one facette (edge or face).
Definition: element.hh:113
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich