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__DOMAIN__
34 : #define __H__UG__LIB_DISC__DOMAIN__
35 :
36 : #include "lib_grid/algorithms/subset_util.h"
37 : #include "lib_grid/refinement/projectors/refinement_projector.h"
38 :
39 : #include <map>
40 :
41 : #ifdef UG_PARALLEL
42 : #include "lib_grid/parallelization/distributed_grid.h"
43 : #endif
44 :
45 : namespace ug{
46 :
47 : /**
48 : * Domain
49 : *
50 : * \defgroup lib_disc_domain Domain
51 : * \ingroup lib_discretization
52 : * \{
53 : */
54 :
55 : /// Describes the contents of a domain.
56 : /** In a parallel environment those are the contents of the global distributed domain.
57 : */
58 : class DomainInfo
59 : {
60 : public:
61 : typedef unsigned long long int_t;
62 :
63 0 : inline int element_type() const {return m_elementType;}
64 0 : inline size_t num_levels() const {return m_numElems.size();}
65 : /// returns the global number of elements on the given level (excluding ghosts...)
66 0 : inline size_t num_elements_on_level(size_t lvl) const {return (size_t)m_numElems[lvl];}
67 : /// returns the global number of surface elements (elements without children)
68 0 : inline size_t num_surface_elements() const {return (size_t)m_numSurfElems;}
69 : /// returns the local number of elements on the given level (excluding ghosts...)
70 0 : inline size_t num_local_elements_on_level(size_t lvl) const {return (size_t)m_numLocalElems[lvl];}
71 : /// returns the minimum number of elements a process has on a given leven (excluding ghosts)
72 : inline size_t min_num_local_elements_on_level(size_t lvl) const {return (size_t)m_minNumLocalElems[lvl];}
73 : /// returns the maximum number of elements a process has on a given leven (excluding ghosts)
74 : inline size_t max_num_local_elements_on_level(size_t lvl) const {return (size_t)m_maxNumLocalElems[lvl];}
75 : /// returns the local number of ghosts on the given level
76 0 : inline size_t num_local_ghosts_on_level(size_t lvl) const {return (size_t)m_numLocalGhosts[lvl];}
77 :
78 0 : inline size_t num_subsets() const
79 0 : {return m_subsetDims.size();}
80 0 : inline size_t subset_dim(int si) const
81 0 : {return m_subsetDims[si];}
82 :
83 0 : inline size_t num_elements() const
84 : {
85 : int_t total = 0;
86 0 : for(size_t i = 0; i < m_numElems.size(); ++i){
87 0 : total += m_numElems[i];
88 : }
89 0 : return (size_t)total;
90 : }
91 :
92 0 : inline void set_info(GridBaseObjectId elemType,
93 : const std::vector<int_t>& numElems,
94 : const std::vector<int_t>& numLocalElems,
95 : const std::vector<int_t>& minNumLocalElems,
96 : const std::vector<int_t>& maxNumLocalElems,
97 : const std::vector<int_t>& numLocalGhosts,
98 : const std::vector<int_t>& subsetDims,
99 : int_t numSurfElems)
100 0 : {m_elementType = elemType;
101 0 : m_numElems = numElems;
102 0 : m_numLocalElems = numLocalElems;
103 0 : m_minNumLocalElems = minNumLocalElems;
104 0 : m_maxNumLocalElems = maxNumLocalElems;
105 0 : m_numLocalGhosts = numLocalGhosts;
106 0 : m_subsetDims = subsetDims;
107 0 : m_numSurfElems = numSurfElems;
108 0 : }
109 :
110 : std::string to_string() const;
111 :
112 : private:
113 : GridBaseObjectId m_elementType;
114 : std::vector<int_t> m_numElems;
115 : std::vector<int_t> m_numLocalElems;///< local number of elements excluding ghosts.
116 : std::vector<int_t> m_minNumLocalElems;
117 : std::vector<int_t> m_maxNumLocalElems;
118 : std::vector<int_t> m_numLocalGhosts;
119 : std::vector<int_t> m_subsetDims;
120 : int_t m_numSurfElems;
121 : };
122 :
123 :
124 : /// describes a physical domain
125 : /**
126 : * A Domain collects and exports relevant information about the
127 : * physical domain, that is intended to be discretized. It will be used as
128 : * a template Parameter in several classes to distinguish at compile-time
129 : * between needed types and parameters. It mainly has a grid and a subset
130 : * handler for the grid to define different physical subsets. In addition
131 : * to a grid, that may only contain topological informations a domain always
132 : * has a Position Attachment holding the physical coordinates.
133 : *
134 : * \tparam TGrid Grid type
135 : * \tparam TSubsetHandler Subset Handler type
136 : */
137 : template <typename TGrid = MultiGrid, typename TSubsetHandler = MGSubsetHandler>
138 : class IDomain
139 : {
140 : public:
141 : /// Grid type
142 : typedef TGrid grid_type;
143 :
144 : /// Subset Handler type
145 : typedef TSubsetHandler subset_handler_type;
146 :
147 : public:
148 : /// Default constructor
149 : /**
150 : * creates an empty domain. Grid and Subset Handler are set up. The
151 : * Distributed Grid Manager is set in the parallel case.
152 : * \param[in] options Grid Options (optinal)*/
153 : IDomain(bool isAdaptive = true);
154 :
155 : /// Destructor
156 : virtual ~IDomain();
157 :
158 : /// World Dimension
159 : virtual int get_dim() const = 0;
160 :
161 : /// returns Grid
162 0 : inline SmartPtr<TGrid> grid() {return m_spGrid;};
163 :
164 : /// const access to Grid
165 : inline const ConstSmartPtr<TGrid> grid() const {return m_spGrid;};
166 :
167 : /// returns Subset Handler
168 0 : inline SmartPtr<TSubsetHandler> subset_handler() {return m_spSH;};
169 :
170 : /// const access to Subset Handler
171 : inline const ConstSmartPtr<TSubsetHandler> subset_handler() const {return m_spSH;};
172 :
173 : /// returns the message hub of the grid
174 : SPMessageHub message_hub() {return m_spGrid->message_hub();}
175 :
176 : /// returns whether the domain may be used for adaptive refinement
177 0 : bool is_adaptive() const {return m_isAdaptive;}
178 :
179 : /// returns whether the associated grid is empty
180 : /** Note that one vertex is enough to consider the grid as non-empty.*/
181 0 : bool empty() const {return m_spGrid->num_vertices() == 0;}
182 :
183 : /// updates and broadcasts subset names and dimensions from the given rootProc to all other processes.
184 : void update_subset_infos(int rootProc);
185 :
186 : /// returns information on the current domain
187 : /** In a parallel environment, this information relates to the global
188 : * (distributed) domain.*/
189 0 : const DomainInfo& domain_info() const {return m_domainInfo;}
190 :
191 : /// updates the internal domain-info object.
192 : /** This method is called automatically each time the associated grid has changed.*/
193 : void update_domain_info();
194 :
195 : /// returns whether the domain can be used for parallel computations
196 : /** If ug was build with support for parallelism, this method will always return true
197 : * and always false, if ug was build for serial environments.*/
198 : bool is_parallel() {return m_spGrid->is_parallel();}
199 :
200 : /// returns Distributed Grid Manager
201 : inline DistributedGridManager* distributed_grid_manager() {return m_spGrid->distributed_grid_manager();}
202 :
203 : /// creates an additional subset-handler with the given name
204 : /** If this subset-handler is created before the domain is loaded from a file,
205 : * the contents of the handler will be filled with the contents of the
206 : * file's subset-handler-node with the same name.*/
207 : bool create_additional_subset_handler(std::string name);
208 :
209 : /// returns a list with the names of additional subset handlers
210 : std::vector<std::string> additional_subset_handler_names() const;
211 :
212 : /// returns an additional subset handler Subset Handler
213 : SmartPtr<TSubsetHandler> additional_subset_handler(std::string name);
214 :
215 : /// const access to Subset Handler
216 : const ConstSmartPtr<TSubsetHandler> additional_subset_handler(std::string name) const;
217 :
218 : /// sets the ug::RefinementProjector which can be used by refiners during refinement
219 : void set_refinement_projector(SPRefinementProjector proj);
220 :
221 : /// returns the domain's ug::RefinementProjector. The pointer may be invalid.
222 : SPRefinementProjector refinement_projector() const;
223 :
224 : /// returns the geometry of the domain
225 : virtual SPIGeometry3d geometry3d() const = 0;
226 :
227 : protected:
228 : #ifdef UG_PARALLEL
229 : /// helper method to broadcast ug::RefinementProjectors to different processes
230 : SPRefinementProjector
231 : broadcast_refinement_projector (
232 : int rootProc,
233 : pcl::ProcessCommunicator& procCom,
234 : SPIGeometry3d geometry,
235 : SPRefinementProjector projector = SPNULL);
236 :
237 : void serialize_projector (
238 : BinaryBuffer& bufOut,
239 : SPRefinementProjector proj);
240 :
241 : SPRefinementProjector deserialize_projector (BinaryBuffer& buf);
242 : #endif
243 :
244 : SmartPtr<TGrid> m_spGrid; ///< Grid
245 : SmartPtr<TSubsetHandler> m_spSH; ///< Subset Handler
246 : std::map<std::string, SmartPtr<TSubsetHandler> > m_additionalSH; ///< additional subset handlers
247 :
248 : SPRefinementProjector m_refinementProjector;
249 :
250 : MessageHub::SPCallbackId m_spGridAdaptionCallbackID;
251 : MessageHub::SPCallbackId m_spGridCreationCallbackID;
252 : MessageHub::SPCallbackId m_spGridDistributionCallbackID;
253 :
254 : DomainInfo m_domainInfo;
255 :
256 : bool m_isAdaptive;
257 : bool m_adaptionIsActive;
258 :
259 : /** this callback is called by the message hub, when a grid adaption has been
260 : * performed. It will call all necessary actions in order to keep the grid
261 : * correct for computations. */
262 : inline void grid_adaption_callback(const GridMessage_Adaption& msg);
263 :
264 : /// Called when a domain has been loaded and during domain distribution
265 : inline void grid_creation_callback(const GridMessage_Creation& msg);
266 :
267 : /** this callback is called by the message hub, when a grid has been distributed
268 : * between different processes.*/
269 : inline void grid_distribution_callback(const GridMessage_Distribution& msg);
270 :
271 : #ifdef UG_PARALLEL
272 : protected:
273 : /** make sure that elements of the given type are contained in at most one
274 : * vmaster interface. This is always the case for highest dimensional elements.*/
275 : template <class TElem>
276 : void count_ghosts(std::vector<DomainInfo::int_t>& numGhostsOnLvlOut);
277 : #endif
278 :
279 : /// counts local surface elements which are not ghosts or h-slaves
280 : template <class TElem>
281 : size_t count_local_unique_surface_elements();
282 : };
283 :
284 :
285 : template <int d, typename TGrid = MultiGrid, typename TSubsetHandler = MGSubsetHandler>
286 : class Domain : public IDomain<TGrid, TSubsetHandler>
287 : {
288 : private:
289 : /// base type
290 : typedef IDomain<TGrid, TSubsetHandler> base_type;
291 :
292 : public:
293 : /// World dimension
294 : static const int dim = d;
295 :
296 : /// Type of position coordinates
297 : typedef MathVector<dim> position_type;
298 :
299 : /// Type of Position Attachment
300 : typedef Attachment<position_type> position_attachment_type;
301 :
302 : /// Type of Accessor to the Position Data Attachment
303 : typedef Grid::VertexAttachmentAccessor<position_attachment_type>
304 : position_accessor_type;
305 :
306 : public:
307 : /// Grid type
308 : typedef typename base_type::grid_type grid_type;
309 :
310 : /// Subset Handler type
311 : typedef typename base_type::subset_handler_type subset_handler_type;
312 :
313 : public:
314 : /// Default constructor
315 : /**
316 : * creates an empty domain. Grid and Subset Handler are set up. The
317 : * Distributed Grid Manager is set in the parallel case.
318 : * \param[in] options Grid Options (optional)
319 : */
320 : Domain(bool isAdaptive = true);
321 0 : virtual ~Domain() {};
322 :
323 : /// World Dimension
324 0 : virtual int get_dim() const {return dim;}
325 :
326 : /// returns Position Attachment
327 0 : inline position_attachment_type& position_attachment(){return m_aPos;}
328 :
329 : /// const access to Position Attachment
330 0 : inline const position_attachment_type& position_attachment() const {return m_aPos;}
331 :
332 : /// get Position Accessor
333 0 : inline position_accessor_type& position_accessor() {return m_aaPos;}
334 :
335 : /// const access to Position Accessor
336 0 : inline const position_accessor_type& position_accessor() const{return m_aaPos;}
337 :
338 0 : virtual SPIGeometry3d geometry3d() const {return m_geometry3d;}
339 :
340 : protected:
341 : position_attachment_type m_aPos; ///<Position Attachment
342 : position_accessor_type m_aaPos; ///<Accessor
343 : SPIGeometry3d m_geometry3d;
344 : };
345 :
346 : typedef Domain<1, MultiGrid, MGSubsetHandler> Domain1d;
347 : typedef Domain<2, MultiGrid, MGSubsetHandler> Domain2d;
348 : typedef Domain<3, MultiGrid, MGSubsetHandler> Domain3d;
349 :
350 : } // end namespace ug
351 :
352 : // end group lib_disc_domain
353 : /// \}
354 :
355 : // include implementation
356 : #include "domain_impl.h"
357 :
358 : #endif /* __H__UG__LIB_DISC__DOMAIN__ */
|