3#ifndef DUNE_PDELAB_GRIDOPERATOR_COMMON_BORDERDOFEXCHANGER_HH
4#define DUNE_PDELAB_GRIDOPERATOR_COMMON_BORDERDOFEXCHANGER_HH
9#include <unordered_map>
10#include <unordered_set>
19#include <dune/grid/common/gridenums.hh>
21#include <dune/pdelab/common/borderindexidcache.hh>
22#include <dune/pdelab/common/globaldofindex.hh>
23#include <dune/pdelab/gridfunctionspace/entityindexcache.hh>
66 template<
typename Gr
idOperator>
75 using EntitySet =
typename GFSV::Traits::EntitySet;
76 static const int dim = EntitySet::dimension;
77 using Grid =
typename EntitySet::Traits::GridView::Traits::Grid;
79 typedef typename Grid::Traits::GlobalIdSet IdSet;
83 typedef Dune::PDELab::GlobalDOFIndex<
84 typename GFSV::Ordering::Traits::DOFIndex::value_type,
85 GFSV::Ordering::Traits::DOFIndex::max_depth,
91 typedef std::unordered_map<
92 typename GFSV::Ordering::Traits::DOFIndex,
93 std::unordered_set<GlobalDOFIndex>
97 typedef typename GFSV::Ordering::Traits::DOFIndex RowDOFIndex;
98 typedef typename GFSU::Ordering::Traits::DOFIndex ColDOFIndex;
101 typename RowDOFIndex::TreeIndex,
102 typename BorderPattern::mapped_type::value_type
106 typename RowDOFIndex::TreeIndex,
107 typename BorderPattern::mapped_type::value_type,
108 typename M::field_type
119 : _communication_cache(
std::make_shared<CommunicationCache>(grid_operator))
120 , _entity_set(grid_operator.testGridFunctionSpace().entitySet())
125 _communication_cache = std::make_shared<CommunicationCache>(grid_operator);
128 class CommunicationCache
129 :
public BorderIndexIdCache<GFSV>
133 typedef BorderIndexIdCache<GFSV> BaseT;
137 CommunicationCache(
const GridOperator& go)
138 : BaseT(go.testGridFunctionSpace())
139 , _gfsu(go.trialGridFunctionSpace())
140 , _initialized(false)
141 , _entity_cache(go.testGridFunctionSpace())
144 typedef IdType EntityID;
145 typedef typename GFSU::Ordering::Traits::DOFIndex::TreeIndex ColumnTreeIndex;
146 typedef std::size_t size_type;
148 bool initialized()
const
153 void finishInitialization()
161 _border_pattern.clear();
162 _initialized =
false;
168 assert(initialized());
169 return _border_pattern;
172 template<
typename LFSVCache,
typename LFSUCache,
typename LocalPattern>
173 void addEntries(
const LFSVCache& lfsv_cache,
const LFSUCache& lfsu_cache,
const LocalPattern& pattern)
175 assert(!initialized());
177 for (
typename LocalPattern::const_iterator it = pattern.begin(),
178 end_it = pattern.end();
183 if (lfsv_cache.isConstrained(it->i()) || lfsu_cache.isConstrained(it->j()))
186 const typename LFSVCache::DOFIndex& di = lfsv_cache.dofIndex(it->i());
187 const typename LFSUCache::DOFIndex& dj = lfsu_cache.dofIndex(it->j());
189 size_type row_gt_index = GFSV::Ordering::Traits::DOFIndexAccessor::geometryType(di);
190 size_type row_entity_index = GFSV::Ordering::Traits::DOFIndexAccessor::entityIndex(di);
192 size_type col_gt_index = GFSU::Ordering::Traits::DOFIndexAccessor::geometryType(dj);
193 size_type col_entity_index = GFSU::Ordering::Traits::DOFIndexAccessor::entityIndex(dj);
196 if (!this->isBorderEntity(row_gt_index,row_entity_index) ||
197 !this->isBorderEntity(col_gt_index,col_entity_index))
200 _border_pattern[di].insert(GlobalDOFIndex(this->
id(col_gt_index,col_entity_index),dj.treeIndex()));
205 template<
typename Entity>
206 size_type size(
const Entity& e)
const
208 if (!_gfsu.entitySet().contains(e))
210 _entity_cache.update(e);
212 for (size_type i = 0; i < _entity_cache.size(); ++i)
214 typename BorderPattern::const_iterator it = _border_pattern.find(_entity_cache.dofIndex(i));
215 if (!transfer_dof(i,it))
217 n += it->second.size();
223 template<
typename Buffer,
typename Entity>
224 void gather_pattern(Buffer& buf,
const Entity& e)
const
226 if (!_gfsu.entitySet().contains(e))
228 _entity_cache.update(e);
229 for (size_type i = 0; i < _entity_cache.size(); ++i)
231 typename BorderPattern::const_iterator it = _border_pattern.find(_entity_cache.dofIndex(i));
232 if (!transfer_dof(i,it))
234 for (
typename BorderPattern::mapped_type::const_iterator col_it = it->second.begin(),
235 col_end = it->second.end();
238 buf.write(std::make_pair(_entity_cache.dofIndex(i).treeIndex(),*col_it));
242 template<
typename Buffer,
typename Entity>
243 void gather_data(Buffer& buf,
const Entity& e,
const M& matrix)
const
245 if (!_gfsu.entitySet().contains(e))
247 _entity_cache.update(e);
248 for (size_type i = 0; i < _entity_cache.size(); ++i)
250 typename BorderPattern::const_iterator it = _border_pattern.find(_entity_cache.dofIndex(i));
251 if (!transfer_dof(i,it))
253 for (
typename BorderPattern::mapped_type::const_iterator col_it = it->second.begin(),
254 col_end = it->second.end();
258 typename BaseT::EntityIndex col_entity = this->index(col_it->entityID());
261 GFSU::Ordering::Traits::DOFIndexAccessor::store(dj,col_entity.geometryTypeIndex(),col_entity.entityIndex(),col_it->treeIndex());
262 buf.write(std::make_tuple(_entity_cache.dofIndex(i).treeIndex(),*col_it,matrix(_entity_cache.containerIndex(i),_gfsu.ordering().mapIndex(dj))));
269 bool transfer_dof(size_type i,
typename BorderPattern::const_iterator it)
const
272 if (it == _border_pattern.end())
290 mutable EntityIndexCache<GFSV,true> _entity_cache;
295 template<
typename Pattern>
300 typedef std::size_t size_type;
306 bool contains (
int dim,
int codim)
const
310 (_gfsu.dataHandleContains(codim) ||
311 _gfsv.dataHandleContains(codim));
314 bool fixedSize (
int dim,
int codim)
const
321 template<
typename Entity>
327 return _communication_cache.size(e);
332 template<
typename MessageBuffer,
typename Entity>
338 _communication_cache.gather_pattern(buff,e);
343 template<
typename MessageBuffer,
typename Entity>
349 for (size_type i = 0; i < n; ++i)
354 std::pair<bool,typename CommunicationCache::EntityIndex> col_index = _communication_cache.findIndex(data.second.entityID());
355 if (!col_index.first)
359 GFSV::Ordering::Traits::DOFIndexAccessor::store(di,
361 _entity_set.indexSet().index(e),
365 GFSU::Ordering::Traits::DOFIndexAccessor::store(dj,
366 col_index.second.geometryTypeIndex(),
367 col_index.second.entityIndex(),
368 data.second.treeIndex());
370 _pattern.add_link(_gfsv.ordering().mapIndex(di),_gfsu.ordering().mapIndex(dj));
378 : _communication_cache(dof_exchanger.communicationCache())
379 , _entity_set(dof_exchanger.entitySet())
387 const CommunicationCache& _communication_cache;
388 const EntitySet _entity_set;
400 typedef std::size_t size_type;
406 bool contains(
int dim,
int codim)
const
410 (_gfsu.dataHandleContains(codim) ||
411 _gfsv.dataHandleContains(codim));
414 bool fixedSize(
int dim,
int codim)
const
419 template<
typename Entity>
420 size_type size(
Entity& e)
const
425 return _communication_cache.size(e);
428 template<
typename MessageBuffer,
typename Entity>
429 void gather(MessageBuffer& buff,
const Entity& e)
const
434 _communication_cache.gather_data(buff,e,_matrix);
439 template<
typename MessageBuffer,
typename Entity>
445 for (size_type i = 0; i < n; ++i)
450 std::pair<bool,typename CommunicationCache::EntityIndex> col_index = _communication_cache.findIndex(std::get<1>(data).entityID());
451 if (!col_index.first)
455 GFSV::Ordering::Traits::DOFIndexAccessor::store(di,
457 _entity_set.indexSet().index(e),
461 GFSU::Ordering::Traits::DOFIndexAccessor::store(dj,
462 col_index.second.geometryTypeIndex(),
463 col_index.second.entityIndex(),
464 std::get<1>(data).treeIndex());
466 _matrix(_gfsv.ordering().mapIndex(di),_gfsu.ordering().mapIndex(dj)) += std::get<2>(data);
475 : _communication_cache(dof_exchanger.communicationCache())
476 , _entity_set(dof_exchanger.entitySet())
484 const CommunicationCache& _communication_cache;
485 EntitySet _entity_set;
500 if (_entity_set.gridView().comm().size() > 1)
506 _entity_set.gridView().communicate(data_handle,
512 CommunicationCache& communicationCache()
514 return *_communication_cache;
517 const CommunicationCache& communicationCache()
const
519 return *_communication_cache;
522 std::shared_ptr<CommunicationCache> communicationCacheStorage()
524 return _communication_cache;
527 const EntitySet& entitySet()
const
534 std::shared_ptr<CommunicationCache> _communication_cache;
535 EntitySet _entity_set;
540 template<
typename Gr
idOperator>
541 class NoDataBorderDOFExchanger
546 typedef NoDataBorderDOFExchanger CommunicationCache;
551 NoDataBorderDOFExchanger()
554 NoDataBorderDOFExchanger(
const GridOperator& grid_operator)
560 CommunicationCache& communicationCache()
565 const CommunicationCache& communicationCache()
const
570 void update(
const GridOperator& grid_operator)
576 template<
typename Gr
idOperator>
577 class OverlappingBorderDOFExchanger :
578 public NoDataBorderDOFExchanger<GridOperator>
583 OverlappingBorderDOFExchanger()
586 OverlappingBorderDOFExchanger(
const GridOperator& grid_operator)
CommDataHandleIF describes the features of a data handle for communication in parallel runs using the...
Definition: datahandleif.hh:76
Wrapper class for entities.
Definition: entity.hh:64
@ codimension
Know your own codimension.
Definition: entity.hh:105
IdTypeImp IdType
Type used to represent an id.
Definition: indexidset.hh:456
A generic dynamic dense matrix.
Definition: matrix.hh:559
T block_type
Export the type representing the components.
Definition: matrix.hh:566
Standard grid operator implementation.
Definition: gridoperator.hh:36
const GFSU & trialGridFunctionSpace() const
Get the trial grid function space.
Definition: gridoperator.hh:92
const GFSV & testGridFunctionSpace() const
Get the test grid function space.
Definition: gridoperator.hh:98
A DataHandle class to exchange matrix entries.
Definition: borderdofexchanger.hh:398
A DataHandle class to exchange matrix sparsity patterns.
Definition: borderdofexchanger.hh:298
Helper class for adding up matrix entries on border.
Definition: borderdofexchanger.hh:68
Describes the parallel communication interface class for MessageBuffers and DataHandles.
Definition of the DUNE_DEPRECATED macro for the case that config.h is not available.
void accumulateBorderEntries(const GridOperator &grid_operator, Matrix &matrix)
Sums up the entries corresponding to border vertices.
Definition: borderdofexchanger.hh:498
size_type size(Entity &e) const
How many objects of type DataType have to be sent for a given entity.
Definition: borderdofexchanger.hh:322
NonOverlappingBorderDOFExchanger(const GridOperator &grid_operator)
Constructor. Sets up the local to global relations.
Definition: borderdofexchanger.hh:118
std::unordered_map< typename GFSV::Ordering::Traits::DOFIndex, std::unordered_set< GlobalDOFIndex > > BorderPattern
Data structure for storing border-border matrix pattern entries in a communication-optimized form.
Definition: borderdofexchanger.hh:94
PatternMPIData DataType
Export type of data for message buffer.
Definition: borderdofexchanger.hh:304
void gather(MessageBuffer &buff, const Entity &e) const
Pack data from user to message buffer.
Definition: borderdofexchanger.hh:333
void scatter(MessageBuffer &buff, const Entity &e, size_t n)
Unpack data from message buffer to user.
Definition: borderdofexchanger.hh:344
ValueMPIData DataType
Export type of data for message buffer.
Definition: borderdofexchanger.hh:404
void scatter(MessageBuffer &buff, const Entity &e, size_type n)
Unpack data from message buffer to user.
Definition: borderdofexchanger.hh:440
Empty BorderPattern
Data structure for storing border-border matrix pattern entries in a communication-optimized form.
Definition: borderdofexchanger.hh:549
Helpers for dealing with MPI.
Dune namespace.
Definition: alignedallocator.hh:11
Just an empty class.
Definition: typetraits.hh:53
Traits class for the grid operator.
Definition: gridoperatorutilities.hh:34
JF JacobianField
The field type of the jacobian.
Definition: gridoperatorutilities.hh:69
GFSU TrialGridFunctionSpace
The trial grid function space.
Definition: gridoperatorutilities.hh:37
GFSV TestGridFunctionSpace
The test grid function space.
Definition: gridoperatorutilities.hh:40
Dune::PDELab::Backend::Matrix< MB, Domain, Range, JF > Jacobian
The type of the jacobian.
Definition: gridoperatorutilities.hh:72
Helper classes to provide indices for geometrytypes for use in a vector.