Class documentation of Concepts

Loading...
Searching...
No Matches
meshGraph.hh
1#ifndef meshGraph_hh
2#define meshGraph_hh
3
4#include "hp2D.hh"
5#include "toolbox.hh"
6
7//evtl hp2D
8namespace concepts{
9
10
11
12
13class MacroElementNode;
14
16
17public:
19 node1_ = node1;
20 node2_ = node2;
21 }
22
23 //returns the requested node
24 // i = 0 first, else the second
25 MacroElementNode* node(ushort i){
26 return i ? node2_ : node1_;
27 }
28
29// Vertex* getOrigin() {return origin;}
30// Vertex* getDestination() {return destination;}
31
32private:
33 MacroElementNode* node1_;
34 MacroElementNode* node2_;
35};
36
37//TODO: Ein macroElementNode kennt seine mögliche nachbaranzahl
38// viereck = max 4, dreieck = max 3, usw
39
41
42public:
43
44 MacroElementNode():content_(0), south_(0), east_(0), north_(0), west_(0){};
45
46 MacroElementNode(const hp2D::Quad<Real>* quad): content_(0), south_(0), east_(0), north_(0), west_(0){
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
121protected:
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
144private:
145
146 MeshGraph2_Edge *south_, *east_, *north_, *west_;
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
179
180public:
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
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
300protected:
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
313private:
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
#define conceptsException(exc)
const Key & key() const
Returns the key of the connector.
Definition connector.hh:105
uint key() const
Returns the key.
Definition connector.hh:66
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition meshGraph.hh:122
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition meshGraph.hh:301
virtual Scanner * scan() const =0
Returns a scanner to iterate over the elements of the space.
virtual const concepts::Quad & support() const
Definition quad.hh:194
#define conceptsAssert(cond, exc)
#define DEBUGL(doit, msg)
Definition debug.hh:40
Set< F > makeSet(uint n, const F &first,...)
Definition set.hh:320
unsigned short ushort
Abbreviation for unsigned short.
Definition typedefs.hh:51