Line data Source code
1 : /*
2 : * Copyright (c) 2009-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__LIB_GRID__ATTACHMENT_UTIL__
34 : #define __H__LIB_GRID__ATTACHMENT_UTIL__
35 :
36 : #include <vector>
37 : #include "lib_grid/grid/grid.h"
38 :
39 : namespace ug
40 : {
41 :
42 : /**
43 : * Several methods that ease attachment-handling are grouped here.
44 : *
45 : * \defgroup lib_grid_algorithms_attachment_util attachment util
46 : * \ingroup lib_grid_algorithms
47 : * @{
48 : */
49 :
50 : /// Accesses attachements in different element types at the same time.
51 : /** If the same attachment is attached to vertices, edges, faces and volumes of
52 : * a grid, then this accessor can be used to access them all at once.
53 : */
54 : template <class TAttachment>
55 : class MultiElementAttachmentAccessor
56 : {
57 : public:
58 : typedef typename TAttachment::ValueType ValueType;
59 : typedef typename attachment_value_traits<ValueType>::reference RefType;
60 : typedef typename attachment_value_traits<ValueType>::const_reference ConstRefType;
61 :
62 0 : MultiElementAttachmentAccessor() {}
63 : MultiElementAttachmentAccessor(Grid& g, TAttachment& a, bool vrts = true,
64 : bool edges = true, bool faces = true, bool vols = true)
65 : {
66 0 : access(g, a, vrts, edges, faces, vols);
67 : }
68 :
69 0 : bool access(Grid& g, TAttachment& a, bool vrts = true, bool edges = true,
70 : bool faces = true, bool vols = true)
71 : {
72 : m_aaVrt.invalidate(); m_aaEdge.invalidate();
73 : m_aaFace.invalidate(); m_aaVol.invalidate();
74 :
75 : bool ok = true;
76 0 : if(vrts)
77 : ok &= m_aaVrt.access(g, a);
78 0 : if(edges)
79 : ok &= m_aaEdge.access(g, a);
80 0 : if(faces)
81 : ok &= m_aaFace.access(g, a);
82 0 : if(vols)
83 : ok &= m_aaVol.access(g, a);
84 0 : return ok;
85 : }
86 :
87 : void invalidate()
88 : {
89 : m_aaVrt.invalidate();
90 : m_aaEdge.invalidate();
91 : m_aaFace.invalidate();
92 : m_aaVol.invalidate();
93 : }
94 :
95 : bool is_valid_vertex_accessor() const {return m_aaVrt.valid();}
96 : bool is_valid_edge_accessor() const {return m_aaEdge.valid();}
97 : bool is_valid_face_accessor() const {return m_aaFace.valid();}
98 : bool is_valid_volume_accessor() const {return m_aaVol.valid();}
99 :
100 : RefType operator[](Vertex* e) {return m_aaVrt[e];}
101 : RefType operator[](Edge* e) {return m_aaEdge[e];}
102 : RefType operator[](Face* e) {return m_aaFace[e];}
103 : RefType operator[](Volume* e) {return m_aaVol[e];}
104 0 : RefType operator[](GridObject* e)
105 : {
106 0 : switch(e->base_object_id()){
107 0 : case VERTEX: return m_aaVrt[static_cast<Vertex*>(e)];
108 0 : case EDGE: return m_aaEdge[static_cast<Edge*>(e)];
109 0 : case FACE: return m_aaFace[static_cast<Face*>(e)];
110 0 : case VOLUME: return m_aaVol[static_cast<Volume*>(e)];
111 0 : default: UG_THROW("Unknown element type!");
112 : }
113 : }
114 :
115 : ConstRefType operator[](Vertex* e) const {return m_aaVrt[e];}
116 : ConstRefType operator[](Edge* e) const {return m_aaEdge[e];}
117 : ConstRefType operator[](Face* e) const {return m_aaFace[e];}
118 : ConstRefType operator[](Volume* e) const {return m_aaVol[e];}
119 0 : ConstRefType operator[](GridObject* e) const
120 : {
121 0 : switch(e->base_object_id()){
122 0 : case VERTEX: return m_aaVrt[static_cast<Vertex*>(e)];
123 0 : case EDGE: return m_aaEdge[static_cast<Edge*>(e)];
124 0 : case FACE: return m_aaFace[static_cast<Face*>(e)];
125 0 : case VOLUME: return m_aaVol[static_cast<Volume*>(e)];
126 0 : default: UG_THROW("Unknown element type!");
127 : }
128 : }
129 :
130 : Grid::AttachmentAccessor<Vertex, TAttachment>& vertex_accessor() {return m_aaVrt;}
131 : Grid::AttachmentAccessor<Edge, TAttachment>& edge_accessor() {return m_aaEdge;}
132 : Grid::AttachmentAccessor<Face, TAttachment>& face_accessor() {return m_aaFace;}
133 : Grid::AttachmentAccessor<Volume, TAttachment>& volume_accessor() {return m_aaVol;}
134 :
135 : private:
136 : Grid::AttachmentAccessor<Vertex, TAttachment> m_aaVrt;
137 : Grid::AttachmentAccessor<Edge, TAttachment> m_aaEdge;
138 : Grid::AttachmentAccessor<Face, TAttachment> m_aaFace;
139 : Grid::AttachmentAccessor<Volume, TAttachment> m_aaVol;
140 : };
141 :
142 :
143 : ////////////////////////////////////////////////////////////////////////
144 : /// Instances can be used as compare operators, e.g., for std::sort.
145 : /** Make sure that the specified attachment is attached to the elements of
146 : * the given grid and that a < operator is defined for the attached values!
147 : */
148 : template <class TElem, class TAttachment>
149 : class CompareByAttachment
150 : {
151 : public:
152 : CompareByAttachment(Grid& g, TAttachment& aGID)
153 : {
154 : UG_ASSERT(g.has_attachment<TElem>(aGID),
155 : "Can't compare unattached attachments!");
156 : m_aaGID.access(g, aGID);
157 : }
158 :
159 : bool operator()(TElem* e1, TElem* e2)
160 : {
161 : return m_aaGID[e1] < m_aaGID[e2];
162 : }
163 :
164 : private:
165 : Grid::AttachmentAccessor<TElem, TAttachment> m_aaGID;
166 : };
167 :
168 : ////////////////////////////////////////////////////////////////////////
169 : // SetAttachmentValues
170 : /// sets attachment-values for elements between elemsBegin and elemsEnd.
171 : template <class TAttachmentAccessor, class TIter, class TVal>
172 : void SetAttachmentValues(TAttachmentAccessor& aaVal,
173 : TIter elemsBegin, TIter elemsEnd,
174 : const TVal& val);
175 :
176 : ////////////////////////////////////////////////////////////////////////
177 : // ConvertMathVectorAttachmentValues
178 : /// Fills the dest-attachment with values from the source-attachment.
179 : /**
180 : * TSrcAttachment and TDestAttachment have to have ValueTypes that
181 : * are compatible with ug::MathVector.
182 : *
183 : * Copies values from srcAttachment to destAttachment.
184 : * if destAttachment is not already attached, it will be attached
185 : * automatically. The srcAttachment however has to be attached.
186 : *
187 : * Valid types for TElem are: Vertex, Edge, Face, Volume
188 : *
189 : * If the dimensions do not match, the algorithm behaves as follows:
190 : * dim(src) > dim(dest): Only dim(dest) values are copied per element.
191 : * dim(src) < dim(dest): Values in dimensions >= dim(src) are set to 0.
192 : */
193 : template<class TElem, class TSrcAttachment, class TDestAttachment>
194 : bool ConvertMathVectorAttachmentValues(Grid& grid,
195 : TSrcAttachment& srcAttachment,
196 : TDestAttachment& destAttachment);
197 :
198 :
199 : ////////////////////////////////////////////////////////////////////////
200 : /// copies attachments from one grid to the other
201 : /**
202 : * If aSrc is not attached to srcGrid, false is returned.
203 : * If aDest is not attached to destGrid, it is attached automatically.
204 : *
205 : * The method iterates through the elements specified by TElem
206 : * and copies the attachments.
207 : *
208 : * Call like this: CopyAttachments<Vertex>(...);
209 : */
210 : template <class TElem, class TAttachment>
211 : bool CopyAttachments(Grid& srcGrid, TAttachment& aSrc,
212 : Grid& destGrid, TAttachment& aDest);
213 :
214 : ////////////////////////////////////////////////////////////////////////
215 : /// copies attachments for the specified elements
216 : /**
217 : * If aSrc is not attached to srcGrid, false is returned.
218 : * If aDest is not attached to destGrid, it is attached automatically.
219 : */
220 : template <class TElemIter, class TAttachment>
221 : bool CopyAttachments(Grid& grid, TElemIter elemsBegin, TElemIter elemsEnd,
222 : TAttachment& aSrc, TAttachment& aDest);
223 :
224 : ////////////////////////////////////////////////////////////////////////
225 : /// assigns indices to the elements between begin and end.
226 : /** Indices are stored in the given attachment. Make sure that the
227 : * given attachment-accessor operates on an attachment-pipe at which
228 : * those elements are registered.
229 : */
230 : template <class TIterator, class TAAInt>
231 : void AssignIndices(TIterator begin, TIterator end,
232 : TAAInt& aaInt, int baseIndex = 0);
233 :
234 : ////////////////////////////////////////////////////////////////////////
235 : /// returns the iterator whose element has the specified attachment value.
236 : /** If no element contains the given value, end is returned.
237 : *
238 : * Make sure that the specified attachment accessor operates on the
239 : * specified elements.
240 : */
241 : template <class TIterator, class TAttAcc>
242 : TIterator FindElementByValue(TIterator begin, TIterator end,
243 : const typename TAttAcc::ValueType& val,
244 : TAttAcc& aa);
245 :
246 : /**@}*/ // end of doxygen defgroup command
247 : }// end of namespace
248 :
249 : ////////////////////////////////////////////////
250 : // include implementations of template methods.
251 : #include "attachment_util_impl.hpp"
252 :
253 : #endif
|