Line data Source code
1 : /*
2 : * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG__grid_objects_1d__
34 : #define __H__UG__grid_objects_1d__
35 :
36 : #include "../grid/grid.h"
37 : #include "common/math/ugmath.h"
38 : #include "common/assert.h"
39 : #include "grid_objects_0d.h"
40 :
41 : namespace ug
42 : {
43 :
44 : ////////////////////////////////////////////////////////////////////////
45 : /// These numbers define where in the edge-section-container an edge will be stored.
46 : /** The order of the constants must not be changed! Algorithms may exist that rely on it.*/
47 : enum EdgeContainerSections
48 : {
49 : CSEDGE_NONE = -1,
50 : CSEDGE_REGULAR_EDGE = 0,
51 : CSEDGE_CONSTRAINED_EDGE = 1,
52 : CSEDGE_CONSTRAINING_EDGE = 2
53 : };
54 :
55 :
56 :
57 : ////////////////////////////////////////////////////////////////////////
58 : // RegularEdge
59 : /// Edges connect two vertices.
60 : /**
61 : * The most commonly used edge-type.
62 : *
63 : * \ingroup lib_grid_grid_objects
64 : */
65 : class UG_API RegularEdge : public Edge
66 : {
67 : friend class Grid;
68 : public:
69 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<RegularEdge*>(pObj) != NULL;}
70 :
71 0 : RegularEdge() {}
72 : RegularEdge(Vertex* v1, Vertex* v2)
73 3 : {
74 3 : m_vertices[0] = v1;
75 3 : m_vertices[1] = v2;
76 : }
77 :
78 : RegularEdge(const EdgeDescriptor& descriptor)
79 0 : {
80 0 : m_vertices[0] = descriptor.vertex(0);
81 0 : m_vertices[1] = descriptor.vertex(1);
82 : }
83 :
84 3 : virtual ~RegularEdge() {}
85 :
86 0 : virtual GridObject* create_empty_instance() const {return new RegularEdge;}
87 :
88 6 : virtual int container_section() const {return CSEDGE_REGULAR_EDGE;}
89 0 : virtual ReferenceObjectID reference_object_id() const {return ROID_EDGE;}
90 :
91 : /// virtual refine. Returns pointers to Edge.
92 : /**
93 : * create 2 new edges, connecting the original edges end-points with vrtNew.
94 : * \sa Edge::refine.
95 : */
96 : virtual bool refine(std::vector<Edge*>& vNewEdgesOut,
97 : Vertex* newVertex,
98 : Vertex** pSubstituteVrts = NULL);
99 :
100 : //TODO: Think about this method. It is not safe!
101 : /// non virtual refine. Returns pointers to RegularEdge.
102 : /**
103 : * create 2 new edges, connecting the original edges end-points with vrtNew.
104 : * \sa Edge::refine.
105 : */
106 : bool refine(std::vector<RegularEdge*>& vNewEdgesOut,
107 : Vertex* newVertex,
108 : Vertex** pSubstituteVrts = NULL);
109 : };
110 :
111 : template <>
112 : class geometry_traits<RegularEdge>
113 : {
114 : public:
115 : typedef GenericGridObjectIterator<RegularEdge*, EdgeIterator> iterator;
116 : typedef ConstGenericGridObjectIterator<RegularEdge*, EdgeIterator,
117 : ConstEdgeIterator> const_iterator;
118 :
119 : typedef EdgeDescriptor Descriptor;
120 : typedef Edge grid_base_object;
121 :
122 : enum
123 : {
124 : CONTAINER_SECTION = CSEDGE_REGULAR_EDGE,
125 : BASE_OBJECT_ID = EDGE
126 : };
127 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_EDGE;
128 : };
129 :
130 : typedef geometry_traits<RegularEdge>::iterator RegularEdgeIterator;
131 : typedef geometry_traits<RegularEdge>::const_iterator ConstRegularEdgeIterator;
132 :
133 :
134 :
135 : ////////////////////////////////////////////////////////////////////////
136 : // ConstrainedEdge
137 : /// This edge is a sub-edge of a \sa ConstrainingEdge.
138 : /**
139 : * Edges of this type appear during hanging-vertex-refinement.
140 : * Treat them with care, since they are referenced by other objects,
141 : * i.e. \sa ConstrainingEdge
142 : *
143 : * \ingroup lib_grid_grid_objects
144 : */
145 : class UG_API ConstrainedEdge : public Edge
146 : {
147 : friend class Grid;
148 : public:
149 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<ConstrainedEdge*>(pObj) != NULL;}
150 :
151 0 : ConstrainedEdge() : m_pConstrainingObject(NULL), m_parentBaseObjectId(-1) {}
152 0 : ConstrainedEdge(Vertex* v1, Vertex* v2) :
153 0 : m_pConstrainingObject(NULL),
154 0 : m_parentBaseObjectId(-1)
155 : {
156 0 : m_vertices[0] = v1;
157 0 : m_vertices[1] = v2;
158 : }
159 :
160 0 : ConstrainedEdge(const EdgeDescriptor& descriptor) :
161 0 : m_pConstrainingObject(NULL),
162 0 : m_parentBaseObjectId(-1)
163 : {
164 0 : m_vertices[0] = descriptor.vertex(0);
165 0 : m_vertices[1] = descriptor.vertex(1);
166 0 : }
167 :
168 0 : virtual ~ConstrainedEdge()
169 0 : {
170 0 : if(m_pConstrainingObject)
171 0 : m_pConstrainingObject->remove_constraint_link(this);
172 0 : }
173 :
174 0 : virtual GridObject* create_empty_instance() const {return new ConstrainedEdge;}
175 :
176 0 : virtual int container_section() const {return CSEDGE_CONSTRAINED_EDGE;}
177 0 : virtual ReferenceObjectID reference_object_id() const {return ROID_EDGE;}
178 :
179 0 : virtual bool is_constrained() const {return true;}
180 :
181 0 : virtual void remove_constraint_link(const Edge* e)
182 : {
183 0 : if(m_pConstrainingObject == static_cast<const GridObject*>(e)){
184 0 : m_pConstrainingObject = NULL;
185 : }
186 0 : }
187 :
188 0 : virtual void remove_constraint_link(const Face* f)
189 : {
190 0 : if(m_pConstrainingObject == static_cast<const GridObject*>(f)){
191 0 : m_pConstrainingObject = NULL;
192 : }
193 0 : }
194 :
195 : /// virtual refine. Returns pointers to Edge.
196 : /**
197 : * create 2 new constrained edges, connecting the original edges end-points with vrtNew.
198 : * please note that the caller is responsible to resolve any conflicts arising with
199 : * existing links of constrained/constraining objects.
200 : * \sa Edge::refine.
201 : */
202 : virtual bool refine(std::vector<Edge*>& vNewEdgesOut,
203 : Vertex* newVertex,
204 : Vertex** pSubstituteVrts = NULL);
205 :
206 : //TODO: Think about this method. It is not safe!
207 : /// non virtual refine. Returns pointers to ConstrainedEdge.
208 : /**
209 : * create 2 new constrained edges, connecting the original edges end-points with vrtNew.
210 : * please note that the caller is responsible to resolve any conflicts arising with
211 : * existing links of constrained/constraining objects.
212 : * \sa Edge::refine
213 : */
214 : bool refine(std::vector<ConstrainedEdge*>& vNewEdgesOut,
215 : Vertex* newVertex,
216 : Vertex** pSubstituteVrts = NULL);
217 :
218 : inline void set_constraining_object(GridObject* pObj)
219 : {
220 0 : m_pConstrainingObject = pObj;
221 0 : if(pObj)
222 0 : m_parentBaseObjectId = pObj->base_object_id();
223 0 : }
224 :
225 0 : inline GridObject* get_constraining_object() {return m_pConstrainingObject;}
226 :
227 0 : inline int get_parent_base_object_id() {return m_parentBaseObjectId;}
228 0 : inline void set_parent_base_object_id(int id)
229 : {
230 0 : if((m_parentBaseObjectId != -1) && (m_parentBaseObjectId != id)){
231 0 : UG_THROW("Bad parent base object id specified! The given id"
232 : " has to match the id of the constraining object if that"
233 : " is present. Call this method only, if no constraining"
234 : " object has been set!");
235 : }
236 0 : m_parentBaseObjectId = id;
237 0 : }
238 :
239 :
240 : protected:
241 : GridObject* m_pConstrainingObject;
242 : int m_parentBaseObjectId;
243 : };
244 :
245 : template <>
246 : class geometry_traits<ConstrainedEdge>
247 : {
248 : public:
249 : typedef GenericGridObjectIterator<ConstrainedEdge*, EdgeIterator> iterator;
250 : typedef ConstGenericGridObjectIterator<ConstrainedEdge*, EdgeIterator,
251 : ConstEdgeIterator> const_iterator;
252 :
253 : typedef EdgeDescriptor Descriptor;
254 : typedef Edge grid_base_object;
255 :
256 : enum
257 : {
258 : CONTAINER_SECTION = CSEDGE_CONSTRAINED_EDGE,
259 : BASE_OBJECT_ID = EDGE
260 : };
261 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_EDGE;
262 : };
263 :
264 : typedef geometry_traits<ConstrainedEdge>::iterator ConstrainedEdgeIterator;
265 : typedef geometry_traits<ConstrainedEdge>::const_iterator ConstConstrainedEdgeIterator;
266 :
267 :
268 :
269 : ////////////////////////////////////////////////////////////////////////
270 : // ConstrainingEdge
271 : /// contains elements of type \sa HangingVertex and \sa ConstrainedEdge
272 : /**
273 : * Edges of this type appear during hanging-vertex-refinement.
274 : * Treat with care.
275 : *
276 : * \ingroup lib_grid_grid_objects
277 : */
278 : class UG_API ConstrainingEdge : public Edge
279 : {
280 : friend class Grid;
281 : public:
282 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<ConstrainingEdge*>(pObj) != NULL;}
283 :
284 0 : ConstrainingEdge() {}
285 0 : ConstrainingEdge(Vertex* v1, Vertex* v2)
286 0 : {
287 0 : m_vertices[0] = v1;
288 0 : m_vertices[1] = v2;
289 0 : m_constrainedVertices.reserve(1);
290 0 : m_constrainedEdges.reserve(2);
291 0 : }
292 :
293 0 : ConstrainingEdge(const EdgeDescriptor& descriptor)
294 0 : {
295 0 : m_vertices[0] = descriptor.vertex(0);
296 0 : m_vertices[1] = descriptor.vertex(1);
297 0 : m_constrainedVertices.reserve(1);
298 0 : m_constrainedEdges.reserve(2);
299 0 : }
300 :
301 0 : virtual ~ConstrainingEdge()
302 0 : {
303 0 : for(size_t i = 0; i < m_constrainedVertices.size(); ++i){
304 0 : m_constrainedVertices[i]->remove_constraint_link(this);
305 : }
306 :
307 0 : for(size_t i = 0; i < m_constrainedEdges.size(); ++i){
308 0 : m_constrainedEdges[i]->remove_constraint_link(this);
309 : }
310 0 : }
311 :
312 0 : virtual GridObject* create_empty_instance() const {return new ConstrainingEdge;}
313 :
314 0 : virtual int container_section() const {return CSEDGE_CONSTRAINING_EDGE;}
315 0 : virtual ReferenceObjectID reference_object_id() const {return ROID_EDGE;}
316 :
317 0 : virtual bool is_constraining() const {return true;}
318 :
319 :
320 0 : virtual void remove_constraint_link(const Vertex* vrt)
321 : {
322 0 : unconstrain_object(vrt);
323 0 : }
324 :
325 0 : virtual void remove_constraint_link(const Edge* e)
326 : {
327 0 : unconstrain_object(e);
328 0 : }
329 :
330 :
331 : /// virtual refine. Returns pointers to Edge.
332 : /**
333 : * create 2 new constraining edges, connecting the original edges end-points with vrtNew.
334 : * The refine has no effect on constrained objects. The user has to manually copy them.
335 : * \sa Edge::refine.
336 : */
337 : virtual bool refine(std::vector<Edge*>& vNewEdgesOut,
338 : Vertex* newVertex,
339 : Vertex** pSubstituteVrts = NULL);
340 :
341 : //TODO: Think about this method. It is not safe!
342 : /// non virtual refine. Returns pointers to ConstrainingEdge.
343 : /**
344 : * create 2 new constraining edges, connecting the original edges end-points with vrtNew.
345 : * The refine has no effect on constrained objects. The user has to manually copy them.
346 : * \sa Edge::refine.
347 : */
348 : bool refine(std::vector<ConstrainingEdge*>& vNewEdgesOut,
349 : Vertex* newVertex,
350 : Vertex** pSubstituteVrts = NULL);
351 :
352 :
353 : inline void add_constrained_object(Vertex* pObj)
354 : {
355 : UG_ASSERT(!is_constrained_object(pObj), "vertex is already constrained by this edge.");
356 0 : m_constrainedVertices.push_back(pObj);
357 0 : }
358 :
359 : inline void add_constrained_object(Edge* pObj)
360 : {
361 : UG_ASSERT(!is_constrained_object(pObj), "edge is already constrained by this edge.");
362 0 : m_constrainedEdges.push_back(pObj);
363 0 : }
364 :
365 : inline bool is_constrained_object(Vertex* vrt)
366 : {
367 0 : std::vector<Vertex*>::iterator iter = find(m_constrainedVertices.begin(),
368 : m_constrainedVertices.end(), vrt);
369 : return iter != m_constrainedVertices.end();
370 : }
371 :
372 : inline bool is_constrained_object(Edge* edge)
373 : {
374 0 : std::vector<Edge*>::iterator iter = find(m_constrainedEdges.begin(),
375 : m_constrainedEdges.end(), edge);
376 : return iter != m_constrainedEdges.end();
377 : }
378 :
379 0 : inline void unconstrain_object(const Vertex* vrt)
380 : {
381 0 : std::vector<Vertex*>::iterator iter = find(m_constrainedVertices.begin(),
382 : m_constrainedVertices.end(), vrt);
383 0 : if(iter != m_constrainedVertices.end())
384 0 : m_constrainedVertices.erase(iter);
385 0 : }
386 :
387 0 : inline void unconstrain_object(const Edge* edge)
388 : {
389 0 : std::vector<Edge*>::iterator iter = find(m_constrainedEdges.begin(),
390 : m_constrainedEdges.end(), edge);
391 0 : if(iter != m_constrainedEdges.end())
392 0 : m_constrainedEdges.erase(iter);
393 0 : }
394 :
395 : inline void clear_constrained_vertices() {m_constrainedVertices.clear();}
396 : inline void clear_constrained_edges() {m_constrainedEdges.clear();}
397 : inline void clear_constrained_objects()
398 : {
399 : clear_constrained_vertices();
400 : clear_constrained_edges();
401 : }
402 :
403 : // NUMBER OF CONSTRAINED ELEMENTS
404 : inline size_t num_constrained_vertices() const {return m_constrainedVertices.size();}
405 : inline size_t num_constrained_edges() const {return m_constrainedEdges.size();}
406 :
407 : template <class TElem> size_t num_constrained() const;
408 :
409 :
410 : // ACCESS TO CONSTRAINED ELEMENTS
411 : Vertex* constrained_vertex(size_t ind) const
412 : {
413 : UG_ASSERT(ind < m_constrainedVertices.size(), "bad index");
414 0 : return m_constrainedVertices[ind];
415 : }
416 :
417 : Edge* constrained_edge(size_t ind) const
418 : {
419 : UG_ASSERT(ind < m_constrainedEdges.size(), "bad index");
420 0 : return m_constrainedEdges[ind];
421 : }
422 :
423 : template <class TElem> TElem* constrained(size_t ind) const;
424 :
425 : protected:
426 : std::vector<Vertex*> m_constrainedVertices;
427 : std::vector<Edge*> m_constrainedEdges;
428 : };
429 :
430 : template <>
431 : class geometry_traits<ConstrainingEdge>
432 : {
433 : public:
434 : typedef GenericGridObjectIterator<ConstrainingEdge*, EdgeIterator> iterator;
435 : typedef ConstGenericGridObjectIterator<ConstrainingEdge*, EdgeIterator,
436 : ConstEdgeIterator> const_iterator;
437 :
438 : typedef EdgeDescriptor Descriptor;
439 : typedef Edge grid_base_object;
440 :
441 : enum
442 : {
443 : CONTAINER_SECTION = CSEDGE_CONSTRAINING_EDGE,
444 : BASE_OBJECT_ID = EDGE
445 : };
446 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_EDGE;
447 : };
448 :
449 : typedef geometry_traits<ConstrainingEdge>::iterator ConstrainingEdgeIterator;
450 : typedef geometry_traits<ConstrainingEdge>::const_iterator ConstConstrainingEdgeIterator;
451 :
452 : }// end of namespace
453 :
454 : #endif
|