3#ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_LOADBALANCE_HH
4#define DUNE_PDELAB_GRIDFUNCTIONSPACE_LOADBALANCE_HH
6#include <dune/geometry/dimension.hh>
8#include <dune/grid/common/partitionset.hh>
10#include<dune/pdelab/common/polymorphicbufferwrapper.hh>
11#include <dune/pdelab/gridfunctionspace/entityindexcache.hh>
23 template<
typename... T>
24 class LoadBalanceDataHandle
26 typename std::decay<typename std::tuple_element<0,std::tuple<T...>>::type>::type
27 ::Map::mapped_type::value_type>
31 using R0 =
typename std::decay<
typename std::tuple_element<0,std::tuple<T...>>::type>::type
32 ::Map::mapped_type::value_type;
34 LoadBalanceDataHandle(std::tuple<T&...>&& mapTuple)
40 bool contains (
int dim,
int codim)
const
58 template <std::
size_t I,
typename EntityType>
59 inline typename std::enable_if<I==
sizeof...(T),
void>::type
60 sizeTMP(std::size_t& commSize, EntityType& e)
const
65 template <std::
size_t I=0,
typename EntityType>
66 inline typename std::enable_if<I<
sizeof...(T),
void>::type
67 sizeTMP(std::size_t& commSize, EntityType& e)
const
70 using R =
typename std::decay<
typename std::tuple_element<I,std::tuple<T...>>::type>::type
71 ::Map::mapped_type::value_type;
72 static_assert(std::is_same<R,R0>::value,
"Different field type of vectors not supported by DH");
75 auto& gfs = std::get<I>(_mapTuple)._gfs;
78 if (gfs.finiteElementMap().hasDOFs(e.codimension)){
81 commSize +=
sizeof(R);
84 if (gfs.entitySet().contains(e)){
86 using GFS =
typename std::decay<
decltype(gfs)>::type;
87 using EntitySet =
typename GFS::Traits::EntitySet;
88 using IDSet =
typename EntitySet::Traits::GridView::Grid::LocalIdSet;
91 const IDSet& idSet(gfs.entitySet().gridView().grid().localIdSet());
92 auto& map = std::get<I>(_mapTuple)._map;
93 auto find = map.find(idSet.id(e));
94 assert (find!=map.end());
97 commSize += find->second.size()*
sizeof(R);
102 sizeTMP<I+1>(commSize,e);
106 template<
class EntityType>
107 std::size_t size (EntityType& e)
const
110 std::size_t commSize(0.0);
111 sizeTMP<0>(commSize,e);
117 template <std::
size_t I,
typename Buf,
typename Entity>
118 inline typename std::enable_if<I==
sizeof...(T),
void>::type
119 gatherTMP(Buf& buf,
const Entity& e)
const
124 template <std::
size_t I=0,
typename Buf,
typename Entity>
125 inline typename std::enable_if<I<
sizeof...(T),
void>::type
126 gatherTMP(Buf& buf,
const Entity& e)
const
129 auto& gfs = std::get<I>(_mapTuple)._gfs;
130 auto& map = std::get<I>(_mapTuple)._map;
135 if (gfs.finiteElementMap().hasDOFs(e.codimension)){
136 if (gfs.entitySet().contains(e)){
138 using GFS =
typename std::decay<
decltype(gfs)>::type;
139 using EntitySet =
typename GFS::Traits::EntitySet;
140 using IDSet =
typename EntitySet::Traits::GridView::Grid::LocalIdSet;
143 const IDSet& idSet(gfs.entitySet().gridView().grid().localIdSet());
146 auto find = map.find(idSet.id(e));
147 assert (find!=map.end());
150 buf.write (
static_cast<R0
>(find->second.size()));
153 for (
size_t i=0; i<find->second.size(); ++i){
154 buf.write(find->second[i]);
165 gatherTMP<I+1> (buf,e);
169 template<
class MessageBuffer,
class EntityType>
170 void gather (MessageBuffer& buff,
const EntityType& e)
const
177 gatherTMP<0> (bufWrapper,e);
181 template <std::
size_t I,
typename Buf,
typename Entity>
182 inline typename std::enable_if<I==
sizeof...(T),
void>::type
183 scatterTMP(Buf& buf,
const Entity& e)
const
188 template <std::
size_t I=0,
typename Buf,
typename Entity>
189 inline typename std::enable_if<I<
sizeof...(T),
void>::type
190 scatterTMP(Buf& buf,
const Entity& e)
const
192 auto& gfs = std::get<I>(_mapTuple)._gfs;
193 auto& map = std::get<I>(_mapTuple)._map;
194 if (gfs.finiteElementMap().hasDOFs(e.codimension)){
199 std::size_t numberOfEntries(0);
200 numberOfEntries = (size_t) tmp;
203 std::vector<R0> dofs(numberOfEntries);
204 for (
size_t i=0; i<numberOfEntries; ++i){
209 const auto& id_set = gfs.entitySet().grid().localIdSet();
210 map.insert({{id_set.id(e),dofs}});
214 scatterTMP<I+1> (buf,e);
224 template<
class MessageBuffer,
class EntityType>
225 void scatter (MessageBuffer& buff,
const EntityType& e,
size_t n)
232 scatterTMP<0> (bufWrapper, e);
237 std::tuple<T&...>& _mapTuple;
242 template <
typename GFS,
typename V,
typename MAP,
int codim>
243 void loadBalanceMapFiller (
const GFS& gfs, V& v, MAP& map)
245 using IndexCache = Dune::PDELab::EntityIndexCache<GFS>;
246 using LocalView =
typename V::template LocalView<IndexCache>;
247 IndexCache indexCache(gfs);
248 LocalView localView(v);
249 const auto& id_set = gfs.entitySet().grid().localIdSet();
254 indexCache.update(e);
255 localView.bind(indexCache);
258 std::vector<typename LocalView::ElementType> dofs;
259 for (std::size_t i=0; i<localView.size(); ++i){
260 dofs.push_back(localView[i]);
264 map.insert ( {{id_set.id(e),dofs}});
273 struct FillLoadBalanceDOFMap
275 template <
typename GFS,
typename V,
typename MAP>
276 static void fillMap (
const GFS& gfs, V& v, MAP& map)
278 if (gfs.finiteElementMap().hasDOFs(codim)){
279 loadBalanceMapFiller<GFS,V,MAP,codim>(gfs,v,map);
281 FillLoadBalanceDOFMap<codim-1>::fillMap(gfs,v,map);
285 struct FillLoadBalanceDOFMap<0>
287 template <
typename GFS,
typename V,
typename MAP>
288 static void fillMap (
const GFS& gfs, V& v, MAP& map)
290 if (gfs.finiteElementMap().hasDOFs(0)){
291 loadBalanceMapFiller<GFS,V,MAP,0>(gfs,v,map);
297 template <
typename GFS,
typename V,
typename MAP,
int codim>
298 void loadBalanceMapReader (
const GFS& gfs, V& v, MAP& map)
300 using IndexCache = Dune::PDELab::EntityIndexCache<GFS>;
301 using LocalView =
typename V::template LocalView<IndexCache>;
302 IndexCache indexCache(gfs);
303 LocalView localView(v);
304 const auto& id_set = gfs.entitySet().grid().localIdSet();
309 indexCache.update(e);
310 localView.bind(indexCache);
313 auto find = map.find(id_set.id(e));
314 auto& dofs(find->second);
317 assert(find!=map.end());
318 assert(dofs.size()==localView.size());
321 for (std::size_t i=0; i<dofs.size(); ++i){
322 localView[i]=dofs[i];
335 struct ReadLoadBalanceDOFMap
337 template <
typename GFS,
typename V,
typename MAP>
338 static void readMap (
const GFS& gfs, V& v, MAP& map)
340 if (gfs.finiteElementMap().hasDOFs(codim)){
341 loadBalanceMapReader<GFS,V,MAP,codim>(gfs,v,map);
343 ReadLoadBalanceDOFMap<codim-1>::readMap(gfs,v,map);
347 struct ReadLoadBalanceDOFMap<0>
349 template <
typename GFS,
typename V,
typename MAP>
350 static void readMap (
const GFS& gfs, V& v, MAP& map)
352 if (gfs.finiteElementMap().hasDOFs(0)){
353 loadBalanceMapReader<GFS,V,MAP,0>(gfs,v,map);
360 template <
typename G,
typename M>
367 GFSAndMap (GFS& gfs, Map& m) : _gfs(gfs), _map(m)
376 template <
typename GFS,
typename M>
377 GFSAndMap<GFS,M> packGFSAndMap(GFS& gfs, M& m)
379 GFSAndMap<GFS,M> pack(gfs,m);
385 template <
typename Grid,
typename... T>
386 void iteratePacks(Grid& grid, std::tuple<T&...>&& mapTuple);
387 template <
typename Grid,
typename... T,
typename X,
typename... XS>
388 void iteratePacks(Grid& grid, std::tuple<T&...>&& mapTuple, X& x, XS&... xs);
393 template<std::size_t I = 0,
typename Grid,
typename... T,
typename X,
typename... XS>
394 inline typename std::enable_if<I == std::tuple_size<typename X::Tuple>::value,
void>::type
395 iterateTuple(Grid& grid, std::tuple<T&...>&& mapTuple, X& x, XS&... xs)
398 iteratePacks(grid,std::move(mapTuple),xs...);
414 template<std::size_t I = 0,
typename Grid,
typename... T,
typename X,
typename... XS>
415 inline typename std::enable_if<I < std::tuple_size<typename X::Tuple>::value,
void>::type
416 iterateTuple(Grid& grid, std::tuple<T&...>&& mapTuple, X& x, XS&... xs)
419 using GFS =
typename X::GFS;
420 using Tuple =
typename X::Tuple;
421 using V =
typename std::decay<typename std::tuple_element<I,Tuple>::type>::type;
423 using ID =
typename IDSet::IdType;
424 using R =
typename V::field_type;
427 using MAP = std::unordered_map<ID,std::vector<R>>;
429 FillLoadBalanceDOFMap<GFS::Traits::GridView::dimension>::fillMap(x._gfs,std::get<I>(x._tuple),map);
432 auto mapPack = packGFSAndMap(x._gfs,map);
433 auto newMapTuple = std::tuple_cat(mapTuple,std::tie(mapPack));
437 iterateTuple<I+1>(grid,std::move(newMapTuple),x,xs...);
440 std::get<I>(x._tuple) = V(x._gfs,0.0);
441 ReadLoadBalanceDOFMap<GFS::Traits::GridView::dimension>::readMap(x._gfs,std::get<I>(x._tuple),map);
444 template <
typename... T>
445 LoadBalanceDataHandle<T...> createLoadBalanceDataHandle (std::tuple<T&...>&& mapTuple)
447 LoadBalanceDataHandle<T...> dh(std::move(mapTuple));
454 template <
typename Grid,
typename... T>
455 void iteratePacks(Grid& grid, std::tuple<T&...>&& mapTuple)
458 auto dh = createLoadBalanceDataHandle(std::move(mapTuple));
460 std::cout <<
"Calling load balance with data communication" << std::endl;
461 grid.loadBalance(dh);
479 template <
typename Grid,
typename... T,
typename X,
typename... XS>
480 void iteratePacks(Grid& grid, std::tuple<T&...>&& mapTuple, X& x, XS&... xs)
482 iterateTuple(grid,std::move(mapTuple),x,xs...);
498 template <
typename Grid,
typename... X>
499 void loadBalanceGrid(Grid& grid, X&... x)
502 std::tuple<> mapTuple;
505 impl::iteratePacks(grid,std::move(mapTuple),x...);
CommDataHandleIF describes the features of a data handle for communication in parallel runs using the...
Definition: datahandleif.hh:76
GridFamily::Traits::LocalIdSet LocalIdSet
A type that is a model of Dune::IdSet which provides a unique and persistent numbering for all entiti...
Definition: grid.hh:512
Wrapper for message buffers of grid DataHandles that allows for sending different types of data.
Definition: polymorphicbufferwrapper.hh:32
Describes the parallel communication interface class for MessageBuffers and DataHandles.
constexpr InteriorBorder interiorBorder
PartitionSet for the interior and border partitions.
Definition: partitionset.hh:285
Dune namespace.
Definition: alignedallocator.hh:11
Static tag representing a codimension.
Definition: dimension.hh:22
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:272