ug4
Loading...
Searching...
No Matches
load_balancing_impl.hpp
Go to the documentation of this file.
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__load_balancing_impl__
34#define __H__UG__load_balancing_impl__
35
36#include <vector>
37#include "load_balancing.h"
41
42namespace ug
43{
44
47
49template <class TElem, class TIterator, class TAAPos>
51 TIterator begin, TIterator end,
52 int numCellsX, int numCellsY, int numCellsZ,
53 TAAPos& aaPos,
54 typename Grid::traits<TElem>::callback cbConsiderElem,
55 int bucketSubset)
56{
57 using namespace ug;
58 using namespace std;
59
60 typedef typename TAAPos::ValueType vector_t;
61
62// make sure that the dimension is right
63 UG_STATIC_ASSERT(TAAPos::ValueType::Size >= 2,
64 TAPosition_has_to_be_at_least_two_dimensional);
65
66 UG_ASSERT(shOut.grid(), "A grid has to be associated with the "
67 "specified subset handler.");
68
69 if((numCellsX < 1) || (numCellsY < 1) || (numCellsZ < 1)){
70 UG_THROW("At least one cell per direction should be specified.");
71 }
72
73 Grid& grid = *shOut.grid();
74
75// collect all elements which shall be considered for partitioning.
76// All others are assigned to bucketSubset
77 vector<TElem*> elems;
78 for(TIterator iter = begin; iter != end; ++iter){
79 if(cbConsiderElem(*iter))
80 elems.push_back(*iter);
81 else
82 shOut.assign_subset(*iter, bucketSubset);
83 }
84
85// calculate the bounding box
86 vector_t tmin(0), tmax(0);
87 {
88 grid.begin_marking();
89 vector<Vertex*> vrts, associatedVrts;
90 for(TIterator iter = begin; iter != end; ++iter){
91 CollectAssociated(vrts, grid, *iter);
92 for(size_t i = 0; i < vrts.size(); ++i){
93 if(!grid.is_marked(vrts[i])){
94 associatedVrts.push_back(vrts[i]);
95 grid.mark(vrts[i]);
96 }
97 }
98 }
99 grid.end_marking();
100
101 CalculateBoundingBox(tmin, tmax, associatedVrts.begin(),
102 associatedVrts.end(), aaPos);
103 }
104
105 vector3 min, max;
106 VecCopy(min, tmin, 0);
107 VecCopy(max, tmax, 0);
108
109 number width = max.x() - min.x();
110 number height = max.y() - min.y();
111 number depth = max.z() - min.z();
112
113 if((width < SMALL) && numCellsX > 1){
114 UG_LOG("Can't execute PartitionElements_Rectangle: Geometry has no width.\n");
115 return false;
116 }
117 if((height < SMALL) && numCellsY > 1){
118 UG_LOG("Can't execute PartitionElements_Rectangle: Geometry has no height.\n");
119 return false;
120 }
121 if((depth < SMALL) && numCellsZ > 1){
122 UG_LOG("Can't execute PartitionElements_Rectangle: Geometry has no height.\n");
123 return false;
124 }
125
126
127// iterate over all elements and calculate the index at which they shall be
128// inserted into the subset handler
129 for(typename vector<TElem*>::iterator iter = elems.begin();
130 iter != elems.end(); ++iter)
131 {
132 TElem* elem = *iter;
133 vector3 center;
134 VecCopy(center, CalculateCenter(elem, aaPos), 0);
135
136 // get the cell index
137 int xInd = 0;
138 if(numCellsX > 1)
139 xInd = (int)((number)numCellsX * (center.x() - min.x()) / width);
140 int yInd = 0;
141 if(numCellsY > 1)
142 yInd = (int)((number)numCellsY * (center.y() - min.y()) / height);
143 int zInd = 0;
144 if(numCellsZ > 1)
145 zInd = (int)((number)numCellsZ * (center.z() - min.z()) / depth);
146
147 // calculate the subset index (one could think of several alternatives here)
148 int si = zInd * numCellsX * numCellsY + yInd * numCellsX + xInd;
149
150 // assign the subset
151 shOut.assign_subset(elem, si);
152 }
153 return true;
154}
155}// end of namespace
156
157#endif
158
159
160
161
162
163
164
165// This is some old and unmaintained code.
166// Maybe it will be useful somewhen...
195/*
196template <class TElem, int IDimension>
197bool PartitionElementsByRepeatedIntersectionKD(ug::SubsetHandler& shOut,
198 ug::Grid& grid,
199 int numSubsets,
200 ug::APosition& aVrtPos)
201{
202// TODO: move implementation to separate ..._impl.hpp file.
203 using namespace ug;
204 using namespace std;
205
206 typedef KDTreeStatic<APosition, IDimension> KDTree;
207 typedef typename geometry_traits<TElem>::iterator ElemIterator;
208
209// get the max-size from the number of subsets that shall be constructed
210 int treeDepth = 0;
211 int numLeafs = 1;
212 while(numLeafs < numSubsets)
213 {
214 treeDepth++;
215 numLeafs *= 2;
216 }
217
218 if(numLeafs != numSubsets)
219 {
220 LOG("PROBLEM in PartitionElementsByRepeatedIntersection: ");
221 LOG("numSubsets has to be chosen as a power of 2)\n");
222 return false;
223 }
224
225// fill a kd-tree with the vertices. This will help to find the elem-partition later on.
226 KDTree kdTree;
227 kdTree.create_from_grid(grid, grid.vertices_begin(), grid.vertices_end(),
228 aVrtPos, treeDepth, 1, KDSD_CIRCULAR);
229
230// get the leafs
231 vector<typename KDTree::Node*> vLeafs;
232 kdTree.get_leafs(vLeafs);
233
234 if(vLeafs.size() != numLeafs)
235 {
236 // the algorithm failed, since it is not suited to deal with the
237 // given grid and the given parameters.
238 // You could try to distribute your grid onto less processes.
239 // The problem is, that the amount of vertices on both sides of a cut
240 // is not the same. This could be improved, by not choosing the cut-plane
241 // in the kd-tree in a geometric way, but by choosing it so, that
242 // the amount of vertices on both sides equals.
243 // To avoid this problem you could try to rotate your grid. Try to align it
244 // with the x, y and z axis - or write a better algorithm! This one is only
245 // suited for simple test-problems!!!
246 LOG("PROBLEM in PartitionElementsByRepeatedIntersection: ");
247 LOG("could not find the correct intersections.\n");
248 LOG("This can happen depending on the properties of the grid.\n");
249 LOG("Search the source-code for more informations.\n");
250 return false;
251 }
252
253 shOut.clear();
254
255// we need a vertex-selector
256 VertexSelector sel(grid);
257
258// iterate through the leafs. They are sorted in a special way.
259 for(uint i = 0; i < vLeafs.size(); ++i)
260 {
261 // select all vertices of the leaf.
262 sel.select(vLeafs[i]->m_pvVertices->begin(), vLeafs[i]->m_pvVertices->end());
263
264 // now iterate through the elements of the grid.
265 for(ElemIterator iter = grid.begin<TElem>(); iter != grid.end<TElem>(); ++iter)
266 {
267 // push all elements that do not reference unselected vertices into the i-th subset.
268 // all elements will be assigned to a subset this way, since all vertices are
269 // selected in the last iteration.
270 TElem* ele = *iter;
271 // make sure, that the element is not already assigned to a subset.
272 if(shOut.get_subset_index(ele) == -1)
273 {
274 bool bAllSelected = true;
275 for(int j = 0; j < ele->num_vertices(); ++j)
276 {
277 if(!sel.is_selected(ele->vertex(j)))
278 {
279 bAllSelected = false;
280 break;
281 }
282 }
283
284 // if all vertices were selected, we'll push the element to the subset.
285 if(bAllSelected)
286 shOut.assign_subset(ele, i);
287 }
288 }
289 }
290
291//TODO: exchange elements between subsets until all subsets meet a certain criterion.
292
293 return true;
294}
295*/
Manages the elements of a grid and their interconnection.
Definition grid.h:132
void end_marking()
ends a marking sequence. Call this method when you're done with marking.
Definition grid.cpp:1285
bool is_marked(GridObject *obj) const
returns true if the object is marked, false if not.
Definition grid_impl.hpp:843
void mark(GridObject *obj)
marks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
Definition grid_impl.hpp:773
void begin_marking()
begin marking.
Definition grid.cpp:1262
Partitions elements of a grid into several subsets.
Definition subset_handler_grid.h:53
void assign_subset(Vertex *elem, int subsetIndex)
assigns a vertex to a subset.
Definition subset_handler_grid.cpp:204
Grid * grid() const
returns a pointer to the grid on which the subset-handler works.
Definition subset_handler_interface.cpp:304
UG_API void CollectAssociated(std::vector< Vertex * > &vVertexOut, Grid &grid, GridObject *obj, bool clearContainer=true)
Definition grid_util_impl.hpp:169
bool PartitionElements_RegularGrid(SubsetHandler &shOut, TIterator begin, TIterator end, int numCellsX, int numCellsY, int numCellsZ, TAAPos &aaPos, typename Grid::traits< TElem >::callback cbConsiderElem=ConsiderAll(), int bucketSubset=-1)
Partitions the elements in the grid by sorting them into a regular grid.
Definition load_balancing_impl.hpp:50
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_THROW(msg)
Definition error.h:57
#define UG_STATIC_ASSERT(expr, msg)
Checks an expression at compile-time and raises a compile-error if the expression equals 0.
Definition static_assert.h:63
#define UG_LOG(msg)
Definition log.h:367
double number
Definition types.h:124
void CalculateCenter(vector_t &centerOut, const vector_t *pointSet, size_t numPoints)
calculates the center of a point-set
Definition math_util_impl.hpp:98
void VecCopy(vector_target_t &target, const vector_source_t &source, typename vector_target_t::value_type fill)
Copy contents between vectors of possibly different types.
Definition math_vector_functions_common_impl.hpp:56
Definition smart_pointer.h:814
the ug namespace
const number SMALL
Definition math_constants.h:41
AABox< typename TAAPos::ValueType > CalculateBoundingBox(Vertex *e, TAAPos aaPos)
calculates the smallest axis aligned box that contains the given vertex
Definition bounding_box_util.h:43
boost::function< bool(base_object *)> callback
callback type for the elements base type.
Definition grid.h:150