Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
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__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION__
34 : #define __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION__
35 :
36 : #include "lib_disc/local_finite_element/local_finite_element_id.h"
37 : #include "lib_disc/dof_manager/function_pattern.h"
38 : #include "lib_disc/common/local_algebra.h"
39 : #include "approximation_space.h"
40 : #include "lib_disc/dof_manager/dof_distribution.h"
41 :
42 : #ifdef UG_PARALLEL
43 : #include "lib_algebra/parallelization/parallel_storage_type.h"
44 : #endif
45 :
46 : namespace ug{
47 :
48 : /// Base class for all Grid Functions
49 : /**
50 : * This class is the base class for all grid functions. It basically only
51 : * stores the Dof distribution and registers itself at the DoFDistribution on
52 : * creation, such that the Grid function is adapted when the Distribution is
53 : * changed.
54 : */
55 0 : class IGridFunction
56 : {
57 : public:
58 0 : virtual ~IGridFunction() {}
59 :
60 : /// permutes all values
61 : /**
62 : * This method permutes the values according to the passed mapping vector, i.e.
63 : * it performs a permutation of the whole index set. The vector vIndNew must
64 : * have the size of the number of indices and for each index it must return
65 : * the new index, i.e. newIndex = vIndNew[oldIndex].
66 : *
67 : * \param[in] vIndNew mapping for each index
68 : * \returns success flag
69 : */
70 : virtual void permute_values(const std::vector<size_t>& vIndNew) = 0;
71 :
72 : /// copy values
73 : /**
74 : * This method copies values between indices according to the passed mapping.
75 : * The copy of the values is are performed as:
76 : *
77 : * for all i: newIndex = vIndexMap[i].second
78 : * oldIndex = vIndexMap[i].first
79 : * value[newIndex] <- value[oldIndex]
80 : *
81 : * If the copy operation is known to be a disjunct composition (i.e. each index
82 : * appears only in one operation), this can be specified by a flag. In
83 : * this case the order in which the copying is performed is arbitrary and
84 : * this will save a copy operation of the whole vector.
85 : *
86 : * \param[in] vIndexMap vector of index mappings (indexOld, indexNew)
87 : * \param[in] bDisjunct flag, if permutation disjunct
88 : * \returns success flag
89 : */
90 : virtual void copy_values(const std::vector<std::pair<size_t, size_t> >& vIndexMap,
91 : bool bDisjunct = false) = 0;
92 :
93 : /// resize
94 : /**
95 : * This method resizes the length of the vector.
96 : *
97 : * \param[in] s new size
98 : * \param[in] defaultValue default value for new entries
99 : */
100 : virtual void resize_values(size_t s, number defaultValue = 0.0) = 0;
101 : };
102 :
103 : template <typename TDomain> class AdaptionSurfaceGridFunction;
104 :
105 : /// represents numerical solutions on a grid using an algebraic vector
106 : /**
107 : * A grid function brings approximation space and algebra together. For a given
108 : * DoF Distribution (e.g. a level dof distribution or a surface dof distribution)
109 : * the grid function stores the values of the DoFs in an algebraic vector.
110 : * In addition access to the grid elements is provided and the mapping between
111 : * grid elements and DoFs is provided.
112 : *
113 : * \tparam TDomain domain type
114 : * \tparam TAlgebra algebra type
115 : */
116 : template <typename TDomain, typename TAlgebra>
117 : class GridFunction
118 : : public TAlgebra::vector_type,
119 : public IGridFunction,
120 : public DoFDistributionInfoProvider
121 : {
122 : public:
123 : /// This type
124 : typedef GridFunction<TDomain, TAlgebra> this_type;
125 :
126 : /// Type of Approximation space
127 : typedef ApproximationSpace<TDomain> approximation_space_type;
128 :
129 : /// Domain
130 : typedef TDomain domain_type;
131 :
132 : /// World Dimension
133 : static const int dim = domain_type::dim;
134 :
135 : /// Algebra type
136 : typedef TAlgebra algebra_type;
137 :
138 : /// Vector type used to store dof values
139 : typedef typename algebra_type::vector_type vector_type;
140 :
141 : public:
142 : /// iterator traits
143 : template <typename TElem>
144 : struct traits
145 : {
146 : typedef typename DoFDistribution::traits<TElem>::grid_object grid_object;
147 : typedef typename DoFDistribution::traits<TElem>::iterator iterator;
148 : typedef typename DoFDistribution::traits<TElem>::const_iterator const_iterator;
149 : };
150 :
151 : template <int dim>
152 : struct dim_traits
153 : {
154 : typedef typename DoFDistribution::dim_traits<dim>::grid_base_object grid_base_object;
155 : typedef typename DoFDistribution::dim_traits<dim>::iterator iterator;
156 : typedef typename DoFDistribution::dim_traits<dim>::const_iterator const_iterator;
157 : };
158 :
159 : typedef typename dim_traits<dim>::grid_base_object element_type;
160 : typedef typename dim_traits<dim>::iterator element_iterator;
161 : typedef typename dim_traits<dim>::const_iterator const_element_iterator;
162 :
163 : typedef typename dim_traits<dim-1>::grid_base_object side_type;
164 : typedef typename dim_traits<dim-1>::iterator side_iterator;
165 : typedef typename dim_traits<dim-1>::const_iterator const_side_iterator;
166 :
167 : protected:
168 : /// virtual clone using covariant return type
169 0 : virtual this_type* virtual_clone() const {return new this_type(*this);}
170 :
171 : /// virtual clone using covariant return type excluding values
172 : virtual this_type* virtual_clone_without_values() const;
173 :
174 : public:
175 : /// Initializing Constructor
176 : GridFunction(SmartPtr<ApproximationSpace<TDomain> > spApproxSpace,
177 : SmartPtr<DoFDistribution> spDoFDistr, bool bManage = true);
178 :
179 : /// Initializing Constructor using surface dof distribution
180 : GridFunction(SmartPtr<ApproximationSpace<TDomain> > spApproxSpace, bool bManage = true);
181 :
182 : /// Initializing Constructor using surface dof distribution on a level
183 : GridFunction(SmartPtr<ApproximationSpace<TDomain> > spApproxSpace, int level, bool bManage = true);
184 :
185 : /// Initializing Constructor using a grid level
186 : GridFunction(SmartPtr<ApproximationSpace<TDomain> > spApproxSpace, const GridLevel& gl, bool bManage = true);
187 :
188 : protected:
189 : /// checks the algebra
190 : void check_algebra();
191 :
192 : /// inits the grid function
193 : void init(SmartPtr<ApproximationSpace<TDomain> > spApproxSpace,
194 : SmartPtr<DoFDistribution> spDoFDistr, bool bManage);
195 :
196 : public:
197 : /// Copy constructor
198 0 : GridFunction(const this_type& v) : IGridFunction(v) {assign(v);}
199 :
200 : /// assigns another grid function
201 : this_type& operator=(const this_type& v)
202 : {
203 : if (this!= &v) assign(v);
204 : return *this;
205 : }
206 :
207 : /// assigns constant value
208 : this_type& operator=(number d)
209 : {
210 : vector_type::operator=(d);
211 : return *this;
212 : }
213 :
214 : /// clone including values
215 0 : SmartPtr<this_type> clone() const {return SmartPtr<this_type>(this->virtual_clone());}
216 :
217 :
218 : /// clone excluding values
219 0 : SmartPtr<this_type> clone_without_values() const {return SmartPtr<this_type>(this->virtual_clone_without_values());}
220 :
221 : /// copies the GridFunction v, except that the values are copied.
222 : virtual void clone_pattern(const this_type& v);
223 :
224 : /// assigns another GridFunction
225 : void assign(const this_type& v);
226 :
227 : /// assigns the values of a vector
228 : void assign(const vector_type& v);
229 :
230 : /// Destructor
231 0 : virtual ~GridFunction() {m_spDD->unmanage_grid_function(*this);}
232 :
233 : public:
234 : /// returns dof distribution
235 : /// \{
236 : SmartPtr<DoFDistribution> dof_distribution() {return m_spDD;}
237 : SmartPtr<DoFDistribution> dd() {return dof_distribution();}
238 : /// \}
239 :
240 : /// returns dof distribution
241 : /// \{
242 : ConstSmartPtr<DoFDistribution> dof_distribution() const {return m_spDD;}
243 : ConstSmartPtr<DoFDistribution> dd() const {return dof_distribution();}
244 : /// \}
245 :
246 : /// returns the grid level
247 0 : const GridLevel& grid_level() const {return m_spDD->grid_level();}
248 :
249 : /// iterator for elements where this grid function is defined
250 : /// \{
251 : template <typename TElem>
252 : typename traits<TElem>::const_iterator begin() const
253 0 : {return m_spDD->template begin<TElem>();}
254 :
255 : template <typename TElem>
256 : typename traits<TElem>::const_iterator
257 : begin(SurfaceView::SurfaceConstants validStates) const
258 : {return m_spDD->template begin<TElem>(validStates);}
259 :
260 : template <typename TElem>
261 : typename traits<TElem>::const_iterator end() const
262 0 : {return m_spDD->template end<TElem>();}
263 :
264 : template <typename TElem>
265 : typename traits<TElem>::const_iterator
266 : end(SurfaceView::SurfaceConstants validStates) const
267 0 : {return m_spDD->template end<TElem>(validStates);}
268 :
269 : template <typename TElem>
270 : typename traits<TElem>::const_iterator begin(int si) const
271 0 : {return m_spDD->template begin<TElem>(si);}
272 :
273 : template <typename TElem>
274 : typename traits<TElem>::const_iterator
275 : begin(int si, SurfaceView::SurfaceConstants validStates) const
276 : {return m_spDD->template begin<TElem>(si, validStates);}
277 :
278 : template <typename TElem>
279 : typename traits<TElem>::const_iterator end(int si) const
280 0 : {return m_spDD->template end<TElem>(si);}
281 :
282 : template <typename TElem>
283 : typename traits<TElem>::const_iterator
284 : end(int si, SurfaceView::SurfaceConstants validStates) const
285 : {return m_spDD->template end<TElem>(si, validStates);}
286 : /// \}
287 :
288 : /// returns the adjacend elements
289 : template <typename TElem, typename TBaseElem>
290 : void collect_associated(std::vector<TBaseElem*>& vAssElem,
291 : TElem* elem, bool clearContainer = true) const{
292 : m_spDD->collect_associated(vAssElem, elem, clearContainer);
293 0 : }
294 :
295 : /// returns if the grid object is part of this grid function
296 : template <class TGeomObj>
297 : bool is_contained(TGeomObj* obj) const{
298 : return m_spDD->is_contained(obj);
299 : }
300 :
301 : public:
302 : /// return the number of indices distributed (proc local)
303 : size_t num_indices() const {return m_spDD->num_indices();}
304 :
305 : /// return the number of indices distributed on subset si (proc local)
306 : size_t num_indices(int si) const {return m_spDD->num_indices(si);}
307 :
308 : /// return the number of dofs distributed (global)
309 : /// \{
310 0 : size_t num_dofs() const {return num_dofs(DoFCount::ALL_FCT);}
311 0 : size_t num_dofs(int fct) const {return num_dofs(fct, DoFCount::ALL_SUBSET);}
312 : size_t num_dofs(int fct, int si) const;
313 : /// \}
314 :
315 : /// get all indices of the element
316 : template <typename TElem>
317 : void indices(TElem* elem, LocalIndices& ind, bool bHang = false) const
318 0 : {m_spDD->indices(elem, ind, bHang);}
319 :
320 : /// get multi indices on an finite element in canonical order
321 : template <typename TElem>
322 : size_t dof_indices(TElem* elem, size_t fct, std::vector<DoFIndex>& ind, bool bHang = false, bool bClear = true) const
323 0 : {return m_spDD->dof_indices(elem, fct, ind, bHang, bClear);}
324 :
325 : /// get multi indices on an geometric object in canonical order
326 : template <typename TElem>
327 : size_t inner_dof_indices(TElem* elem, size_t fct, std::vector<DoFIndex>& ind, bool bClear = true) const
328 0 : {return m_spDD->inner_dof_indices(elem, fct, ind, bClear);}
329 :
330 : /// get algebra indices on an geometric object in canonical order
331 : template <typename TElem>
332 : size_t algebra_indices(TElem* elem, std::vector<size_t>& ind, bool bClear = true) const
333 0 : {return m_spDD->algebra_indices(elem, ind, bClear);}
334 :
335 : /// get algebra indices on an geometric object in canonical order
336 : template <typename TElem>
337 : size_t inner_algebra_indices(TElem* elem, std::vector<size_t>& ind, bool bClear = true) const
338 0 : {return m_spDD->inner_algebra_indices(elem, ind, bClear);}
339 :
340 : public:
341 : /// returns domain
342 : SmartPtr<TDomain> domain() {return m_spApproxSpace->domain();}
343 :
344 : /// returns const domain
345 : ConstSmartPtr<TDomain> domain() const {return m_spApproxSpace->domain();}
346 :
347 : /// returns approx space
348 0 : SmartPtr<ApproximationSpace<TDomain> > approx_space() {return m_spApproxSpace;}
349 :
350 : /// returns const domain
351 : ConstSmartPtr<ApproximationSpace<TDomain> > approx_space() const {return m_spApproxSpace;}
352 :
353 : public:
354 : /// return m_bManaged
355 : bool managed() const {return m_bManaged;}
356 :
357 : /// retruns true if the grid-function is redistributed together with the grid in parallel applications
358 : /** \note if redistribution is disabled, values corresponding to elements
359 : * which were received during redistribution will not be initialized
360 : * and my be completely random.*/
361 0 : bool redistribution_enabled() const {return m_bRedistribute;}
362 :
363 : /// enables or disables redistribution for this grid function
364 : /** \note if redistribution is disabled, values corresponding to elements
365 : * which were received during redistribution will not be initialized
366 : * and my be completely random.*/
367 0 : void enable_redistribution(bool enable) {m_bRedistribute = enable;}
368 :
369 : // for debugging purposes. To be removed.
370 0 : void SetConsistentStorageType()
371 : {
372 : #ifdef UG_PARALLEL
373 : this->set_storage_type(PST_CONSISTENT);
374 : #endif
375 0 : }
376 :
377 : /// \copydoc IGridFunction::resize_values
378 : virtual void resize_values(size_t s, number defaultValue = 0.0);
379 :
380 : /// \copydoc IGridFunction::permute_values
381 : virtual void permute_values(const std::vector<size_t>& vIndNew);
382 :
383 : /// \copydoc IGridFunction::copy_values
384 : virtual void copy_values(const std::vector<std::pair<size_t, size_t> >& vIndexMap,
385 : bool bDisjunct = false);
386 :
387 :
388 : protected:
389 : /// message hub id
390 : MessageHub::SPCallbackId m_spGridAdaptionCallbackID;
391 : MessageHub::SPCallbackId m_spGridDistributionCallbackID;
392 :
393 : /// registers at message hub for grid adaption
394 : void register_at_adaption_msg_hub();
395 :
396 : /** this callback is called by the message hub, when a grid change has been
397 : * performed. It will call all necessary actions in order to keep the grid
398 : * correct for computations.*/
399 : void grid_changed_callback(const GridMessage_Adaption& msg);
400 :
401 : /// called during parallel redistribution
402 : void grid_distribution_callback(const GridMessage_Distribution& msg);
403 :
404 : /// adaption grid function for temporary storage of values in grid
405 : SmartPtr<AdaptionSurfaceGridFunction<TDomain> > m_spAdaptGridFct;
406 :
407 : protected:
408 : /// DoF Distribution this GridFunction relies on
409 : SmartPtr<DoFDistribution> m_spDD;
410 :
411 : /// Approximation Space
412 : SmartPtr<ApproximationSpace<TDomain> > m_spApproxSpace;
413 :
414 : /// boolean for DoF Distribution management of grid function
415 : bool m_bManaged;
416 :
417 : /// specifies whether the gridfunction should be redistributed together with the grid.
418 : /** enabled by default */
419 : bool m_bRedistribute;
420 :
421 : /// stores the storage-type from before redistribution
422 : uint m_preDistStorageType;
423 : };
424 :
425 : template <typename TDomain, typename TAlgebra>
426 : const typename TAlgebra::vector_type &getVector(const GridFunction<TDomain, TAlgebra> &t)
427 : {
428 : return *dynamic_cast<const GridFunction<TDomain, TAlgebra>*>(&t);
429 : }
430 :
431 :
432 : template <typename TDomain, typename TAlgebra>
433 : inline std::ostream& operator<< (std::ostream& outStream, const GridFunction<TDomain, TAlgebra>& v)
434 : {
435 : outStream << *dynamic_cast<const GridFunction<TDomain, TAlgebra>*>(&v);
436 : return outStream;
437 : }
438 :
439 : } // end namespace ug
440 :
441 : // include implementation
442 : #include "grid_function_impl.h"
443 :
444 : #endif /* __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION__ */
|