dune-pdelab  2.0.0
permutedordering.hh
Go to the documentation of this file.
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=8 sw=2 sts=2:
3 
4 #ifndef DUNE_PDELAB_ORDERING_PERMUTEDORDERING_HH
5 #define DUNE_PDELAB_ORDERING_PERMUTEDORDERING_HH
6 
7 #include <dune/typetree/typetree.hh>
8 
12 
13 namespace Dune {
14  namespace PDELab {
15 
16  namespace ordering {
17 
18 #ifndef DOXYGEN // implementation internals
19 
20  namespace permuted {
21 
22  struct tag_base
23  {
24 
25  std::vector<std::size_t>& permutation()
26  {
27  return _permutation;
28  }
29 
30  const std::vector<std::size_t>& permutation() const
31  {
32  return _permutation;
33  }
34 
35  private:
36 
37  std::vector<std::size_t> _permutation;
38 
39  };
40 
41  template<std::size_t i>
42  struct base_holder
43  : public tag_base
44  {};
45 
46  } // namespace permuted
47 
48 #endif // DOXYGEN
49 
51 
62  template<typename OrderingTag>
63  struct Permuted
64  : public permuted::base_holder<decorated_ordering_tag<Permuted<OrderingTag>,OrderingTag>::level>
65  , public decorated_ordering_tag<Permuted<OrderingTag>,OrderingTag>
66  {
67 
69  {}
70 
71  Permuted(const OrderingTag& tag)
72  : decorated_ordering_tag<Permuted<OrderingTag>,OrderingTag>(tag)
73  {}
74 
75 #if HAVE_RVALUE_REFERENCES
76 
77  Permuted(OrderingTag&& tag)
78  : decorated_ordering_tag<Permuted<OrderingTag>,OrderingTag>(std::move(tag))
79  {}
80 
81 #endif // HAVE_RVALUE_REFERENCES
82 
83  template<std::size_t i>
84  const permuted::base_holder<i>& permuted() const
85  {
86  return *this;
87  }
88 
89  template<std::size_t i>
90  permuted::base_holder<i>& permuted()
91  {
92  return *this;
93  }
94 
95  };
96 
97  } // namespace ordering
98 
101 
103  template<typename Ordering>
105  : public TypeTree::VariadicCompositeNode<Ordering>
106  , public VirtualOrderingBase<typename Ordering::Traits::DOFIndex,
107  typename Ordering::Traits::ContainerIndex>
108  , public OrderingBase<typename Ordering::Traits::DOFIndex,
109  typename Ordering::Traits::ContainerIndex>
110  {
111  public:
112  typedef typename Ordering::Traits Traits;
113 
114  static const bool has_dynamic_ordering_children = true;
115 
116  static const bool consume_tree_index = false;
117 
118  private:
119 
120  typedef TypeTree::VariadicCompositeNode<Ordering> NodeT;
121 
122  typedef OrderingBase<typename Ordering::Traits::DOFIndex,
123  typename Ordering::Traits::ContainerIndex> BaseT;
124 
125  public:
126 
127  Ordering& ordering()
128  {
129  return this->template child<0>();
130  }
131 
132  const Ordering& ordering() const
133  {
134  return this->template child<0>();
135  }
136 
137 
138  PermutedOrdering(const typename NodeT::NodeStorage& ordering, const ordering::permuted::tag_base& tag)
139  : NodeT(ordering)
140  , BaseT(*this,false,nullptr,this)
141  , _tag(tag)
142  {
143  // copy grid partition information from local ordering.
144  this->setPartitionSet(this->ordering());
145  }
146 
148  : NodeT(r.nodeStorage())
149  , BaseT(r)
150  ,_tag(r._tag)
151  {
152  this->setDelegate(this);
153  }
154 
155 #if HAVE_RVALUE_REFERENCES
156 
158  : NodeT(r.nodeStorage())
159  , BaseT(std::move(r))
160  ,_tag(r._tag)
161  {
162  this->setDelegate(this);
163  }
164 
165 #endif // HAVE_RVALUE_REFERENCES
166 
167  virtual void map_index_dynamic(typename Traits::DOFIndexView di, typename Traits::ContainerIndex& ci) const
168  {
169  ordering().mapIndex(di,ci);
170  ci.back() = _tag.permutation()[ci.back()];
171  }
172 
173  template<typename ItIn, typename ItOut>
174  void map_lfs_indices(ItIn in, const ItIn end, ItOut out) const
175  {
176  for (; in != end; ++in, ++out)
177  {
178  out->back() = _tag.permutation()[out->back()];
179  }
180  }
181 
182  template<typename CIOutIterator>
183  typename Traits::SizeType
184  extract_entity_indices(const typename Traits::DOFIndex::EntityIndex& ei,
185  typename Traits::SizeType child_index,
186  CIOutIterator ci_out, const CIOutIterator ci_end) const
187  {
188  for (; ci_out != ci_end; ++ci_out)
189  {
190  ci_out->back() = _tag.permutation()[ci_out->back()];
191  }
192  }
193 
194  void update()
195  {
196  ordering().update();
197  BaseT::update();
198  if (!_tag.permutation().empty() && _tag.permutation().size() != this->blockCount())
199  DUNE_THROW(PermutedOrderingSizeError,
200  "Size of permutation array does not match block count of ordering: "
201  << _tag.permutation().size()
202  << " != "
203  << this->blockCount()
204  );
205  }
206 
207  private:
208 
209  const ordering::permuted::tag_base& _tag;
210 
211  };
212 
213  namespace ordering {
214 
215  namespace permuted {
216 
217  template<typename GFS, typename Transformation, typename Undecorated, typename Tag>
219  {
220 
222  typedef shared_ptr<transformed_type> transformed_storage_type;
223 
224  static transformed_type transform(const GFS& gfs, const Transformation& t, shared_ptr<Undecorated> undecorated)
225  {
226  return transformed_type(make_tuple(undecorated),gfs.orderingTag().template permuted<Tag::level>());
227  }
228 
229  static transformed_storage_type transform_storage(shared_ptr<const GFS> gfs_pointer, const Transformation& t, shared_ptr<Undecorated> undecorated)
230  {
231  return make_shared<transformed_type>(make_tuple(undecorated),gfs_pointer->orderingTag().template permuted<Tag::level>());
232  }
233 
234  };
235 
236  template<typename GFS, typename Transformation, typename Undecorated, typename GlueTag, typename UndecoratedTag>
237  gfs_to_permuted<GFS,Transformation,Undecorated,GlueTag>
238  register_gfs_to_decorator_descriptor(GFS*,Transformation*,Undecorated*,GlueTag*,Permuted<UndecoratedTag>*);
239 
240  } // namespace permuted
241  } // namespace ordering
242 
243 
244  template<typename GFS, typename Transformation, typename U>
245  struct power_gfs_to_local_ordering_descriptor<GFS,Transformation,ordering::Permuted<U> >
246  : public power_gfs_to_local_ordering_descriptor<GFS,Transformation,U>
247  {};
248 
249 
250  template<typename GFS, typename Transformation, typename U>
251  struct composite_gfs_to_local_ordering_descriptor<GFS,Transformation,ordering::Permuted<U> >
252  : public composite_gfs_to_local_ordering_descriptor<GFS,Transformation,U>
253  {};
254 
256  } // namespace PDELab
257 } // namespace Dune
258 
259 #endif // DUNE_PDELAB_ORDERING_PERMUTEDORDERING_HH
Ordering::Traits Traits
Definition: permutedordering.hh:112
static transformed_storage_type transform_storage(shared_ptr< const GFS > gfs_pointer, const Transformation &t, shared_ptr< Undecorated > undecorated)
Definition: permutedordering.hh:229
A PermutedOrdering got a permutation vector of the wrong size.
Definition: exceptions.hh:49
PermutedOrdering< Undecorated > transformed_type
Definition: permutedordering.hh:221
Permuted()
Definition: permutedordering.hh:68
static transformed_type transform(const GFS &gfs, const Transformation &t, shared_ptr< Undecorated > undecorated)
Definition: permutedordering.hh:224
void setPartitionSet(const std::bitset< 6 > &partitions)
Sets the set of contained partitions to the passed-in value.
Definition: partitioninfoprovider.hh:58
Definition: orderingbase.hh:22
permuted::base_holder< i > & permuted()
Definition: permutedordering.hh:90
Definition: ordering/utility.hh:230
shared_ptr< transformed_type > transformed_storage_type
Definition: permutedordering.hh:222
Ordering & ordering()
Definition: permutedordering.hh:127
void map_lfs_indices(ItIn in, const ItIn end, ItOut out) const
Definition: permutedordering.hh:174
Ordering that permutes top-level ContainerIndex entries.
Definition: permutedordering.hh:104
Traits::SizeType extract_entity_indices(const typename Traits::DOFIndex::EntityIndex &ei, typename Traits::SizeType child_index, CIOutIterator ci_out, const CIOutIterator ci_end) const
Definition: permutedordering.hh:184
gfs_to_permuted< GFS, Transformation, Undecorated, GlueTag > register_gfs_to_decorator_descriptor(GFS *, Transformation *, Undecorated *, GlueTag *, Permuted< UndecoratedTag > *)
void update()
Definition: permutedordering.hh:194
static const bool has_dynamic_ordering_children
Definition: permutedordering.hh:114
Permute the ordering created from the passed-in tag based on a simple lookup table.
Definition: permutedordering.hh:63
void update()
Definition: orderingbase.hh:100
virtual void map_index_dynamic(typename Traits::DOFIndexView di, typename Traits::ContainerIndex &ci) const
Definition: permutedordering.hh:167
Permuted(const OrderingTag &tag)
Definition: permutedordering.hh:71
const permuted::base_holder< i > & permuted() const
Definition: permutedordering.hh:84
static const bool consume_tree_index
Definition: permutedordering.hh:116
PermutedOrdering(const typename NodeT::NodeStorage &ordering, const ordering::permuted::tag_base &tag)
Definition: permutedordering.hh:138
const Ordering & ordering() const
Definition: permutedordering.hh:132
PermutedOrdering(const PermutedOrdering &r)
Definition: permutedordering.hh:147
Definition: permutedordering.hh:218
void setDelegate(const VirtualOrderingBase< Ordering::Traits::DOFIndex, Ordering::Traits::ContainerIndex > *delegate)
Set the delegate called in mapIndex().
Definition: orderingbase.hh:227