DUNE PDELab (git)

leafgridviewordering.hh
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_LEAFGRIDVIEWORDERING_HH
5#define DUNE_PDELAB_ORDERING_LEAFGRIDVIEWORDERING_HH
6
7#include <dune/pdelab/ordering/directleaflocalordering.hh>
8#include <dune/pdelab/ordering/leaforderingbase.hh>
9
10namespace Dune {
11 namespace PDELab {
12
15
17 template<typename LocalOrdering>
19 : public LeafOrderingBase<LocalOrdering>
20 {
21 public:
22 typedef typename LocalOrdering::Traits Traits;
23
24 private:
25
26 using ES = typename Traits::EntitySet;
27
29 typedef typename BaseT::NodeT NodeT;
30
31 public:
32
33 LeafGridViewOrdering(const typename NodeT::NodeStorage& local_ordering, bool container_blocked, typename BaseT::GFSData* gfs_data)
34 : BaseT(local_ordering, container_blocked, gfs_data)
35 , _es(this->template child<0>().entitySet())
36 {}
37
38#ifndef DOXYGEN
39
40// we need to override the default copy / move ctor to fix the delegate pointer, but that is
41// hardly interesting to our users...
42
44 : BaseT(r)
45 , _es(r._es)
46 {}
47
49 : BaseT(std::move(r))
50 , _es(r._es)
51 {}
52
53#endif // DOXYGEN
54
55 virtual ~LeafGridViewOrdering() override = default;
56
57
58 using BaseT::size;
59
65 typename Traits::SizeType size(typename Traits::ContainerIndex suffix) const
66 {
67 // notice that this algorithm is the same as for GridViewOrdering
68 // the only difference is that here we can borrow some offsets from the
69 // local ordering
70
71 using size_type = typename Traits::SizeType;
72 if (suffix.size() == Traits::ContainerIndex::max_depth)
73 return 0; // all indices in suffix were consumed, no more sizes to provide
74 if (suffix.size() == 0) // suffix wants the size of this depth
75 return _block_count; // blocked or not, this gives the number of blocks/dofs in next node hierarchy
76
77 // we first have to figure out the entity index
78 typename Traits::DOFIndex::EntityIndex entity_index;
79
80 // the next index to find out its size
81 auto back_index = suffix.back();
82
83 // borrow offsets & fixed_size from local ordering
84 auto& _gt_entity_offsets = this->localOrdering()._gt_entity_offsets;
85 auto& _entity_dof_offsets = this->localOrdering()._entity_dof_offsets;
86 bool _fixed_size = this->localOrdering()._fixed_size;
87 // we just need to make the inverse computation of the mapIndex funtion to find the entity index
88 if (_container_blocked) {
89 suffix.pop_back();
90 auto gt_begin = _fixed_size ? _gt_dof_offsets.begin() : _gt_entity_offsets.begin();
91 auto gt_end = _fixed_size ? _gt_dof_offsets.end() : _gt_entity_offsets.end();
92 auto gt_it = std::prev(std::upper_bound(gt_begin, gt_end, back_index));
93 size_type gt = std::distance(gt_begin, gt_it);
94 assert(back_index >= *gt_it);
95 size_type ei = back_index - *gt_it;
96 Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,gt,ei);
97 } else {
98 auto dof_begin = _fixed_size ? _gt_dof_offsets.begin() : _entity_dof_offsets.begin();
99 auto dof_end = _fixed_size ? _gt_dof_offsets.end() : _entity_dof_offsets.end();
100 auto dof_it = std::prev(std::upper_bound(dof_begin, dof_end, back_index));
101 size_type dof_dist = std::distance(dof_begin, dof_it);
102 if (_fixed_size) {
103 // On fixed size, entity index is not used down the tree. Set max to trigger segfault if this does not hold.
104 Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,dof_dist,~size_type{0});
105 } else {
106 auto gt_begin = _gt_entity_offsets.begin();
107 auto gt_end = _gt_entity_offsets.end();
108 auto gt_it = std::prev(std::upper_bound(gt_begin, gt_end, dof_dist));
109 size_type gt = std::distance(gt_begin, gt_it);
110 assert(dof_dist >= *gt_it);
111 size_type ei = dof_dist - *gt_it;
112 Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,gt,ei);
113 }
114 }
115 // then, the local ordering knows the size for a given entity.
116 return this->localOrdering().size(suffix, entity_index);
117 }
118
119
120 virtual void update() override
121 {
122 LocalOrdering& lo = this->localOrdering();
123 lo.update_a_priori_fixed_size();
124
125 const std::size_t dim = ES::dimension;
126
127 typename ES::CodimMask codims;
128 codims.set(0); // always need cells
129 lo.collect_used_codims(codims);
130
131 for (typename ES::dim_type codim = 0; codim <= ES::dimension; ++codim)
132 if (codims.test(codim))
133 _es.addCodim(codim);
134
135 _es.update();
136
137 typedef typename Traits::SizeType size_type;
138 auto geom_types = _es.indexSet().types();
139
140 if (lo._fixed_size)
141 {
142 lo.update_fixed_size(geom_types.begin(),geom_types.end());
143 }
144 else
145 {
146 lo.pre_collect_used_geometry_types_from_cell();
147
148 for (const auto& element : elements(_es))
149 {
150 lo.collect_used_geometry_types_from_cell(element);
151 }
152
153 lo.allocate_entity_offset_vector(geom_types.begin(),geom_types.end());
154
155 for (const auto& element : elements(_es))
156 {
157 lo.extract_per_entity_sizes_from_cell(element);
158 }
159
160 // FIXME: handling of blocked containers!
161 lo.finalize_non_fixed_size_update();
162 }
163
164 // we need to re-test here, as the local ordering could have detected a fixed size ordering
165 // and switched its implementation
166 if (lo._fixed_size)
167 {
168 _gt_dof_offsets.assign(GlobalGeometryTypeIndex::size(dim) + 1,0);
169 _size = 0;
170
171 for (auto gt : geom_types)
172 {
173 const size_type gt_index = GlobalGeometryTypeIndex::index(gt);
174 size_type gt_size = lo.size(gt_index,0);
175 size_type entity_count = _es.indexSet().size(gt);
176 _size += gt_size * entity_count;
177 if (_container_blocked)
178 gt_size = gt_size > 0;
179 _gt_dof_offsets[gt_index + 1] = gt_size * entity_count;
180 }
181 std::partial_sum(_gt_dof_offsets.begin(),_gt_dof_offsets.end(),_gt_dof_offsets.begin());
182 _block_count = _gt_dof_offsets.back();
183 _codim_fixed_size.set();
184 }
185 else
186 {
187 _block_count = _size = lo._entity_dof_offsets.back();
188 _codim_fixed_size.reset();
189 }
190
191 _fixed_size = lo._fixed_size;
192 _max_local_size = lo.maxLocalSize();
193
194 _codim_used = lo._codim_used;
195 _codim_fixed_size = lo._codim_fixed_size;
196
197 }
198
199 using BaseT::fixedSize;
200
201 private:
202
203 using BaseT::_max_local_size;
204 using BaseT::_size;
205 using BaseT::_block_count;
206 using BaseT::_container_blocked;
207 using BaseT::_fixed_size;
208 using BaseT::_codim_used;
209 using BaseT::_codim_fixed_size;
210 using BaseT::_gt_dof_offsets;
211
212 typename Traits::EntitySet _es;
213 };
214
215
216 template<typename GFS, typename Transformation>
217 struct direct_leaf_gfs_to_gridview_ordering_descriptor
218 {
219
220 static const bool recursive = false;
221
222 typedef DirectLeafLocalOrdering<typename GFS::Traits::OrderingTag,
223 typename GFS::Traits::FiniteElementMap,
224 typename GFS::Traits::EntitySet,
225 typename Transformation::DOFIndex,
226 typename Transformation::ContainerIndex
227 > LocalOrdering;
228
229 typedef LeafGridViewOrdering<LocalOrdering> GridViewOrdering;
230
231 typedef GridViewOrdering transformed_type;
232 typedef std::shared_ptr<transformed_type> transformed_storage_type;
233
234 static transformed_type transform(const GFS& gfs, const Transformation& t)
235 {
236 return transformed_type(make_tuple(std::make_shared<LocalOrdering>(gfs.finiteElementMapStorage(),gfs.entitySet())),gfs.backend().blocked(gfs),const_cast<GFS*>(&gfs));
237 }
238
239 static transformed_storage_type transform_storage(std::shared_ptr<const GFS> gfs, const Transformation& t)
240 {
241 return std::make_shared<transformed_type>(make_tuple(std::make_shared<LocalOrdering>(gfs->finiteElementMapStorage(),gfs->entitySet())),gfs->backend().blocked(*gfs),const_cast<GFS*>(gfs.get()));
242 }
243
244 };
245
246
247 template<typename GFS, typename Transformation, typename Params>
248 direct_leaf_gfs_to_gridview_ordering_descriptor<GFS,Transformation>
249 register_leaf_gfs_to_ordering_descriptor(GFS*,Transformation*,LeafOrderingTag<Params>*);
250
252 } // namespace PDELab
253} // namespace Dune
254
255#endif // DUNE_PDELAB_ORDERING_LEAFGRIDVIEWORDERING_HH
static constexpr std::size_t index(const GeometryType &gt)
Compute the index for the given geometry type over all dimensions.
Definition: typeindex.hh:138
static constexpr std::size_t size(std::size_t maxdim)
Compute total number of geometry types up to and including the given dimension.
Definition: typeindex.hh:125
Gridview ordering for leaf spaces.
Definition: leafgridviewordering.hh:20
virtual void update() override
Definition: leafgridviewordering.hh:120
Traits::SizeType size(typename Traits::ContainerIndex suffix) const
Gives the size for a given suffix.
Definition: leafgridviewordering.hh:65
Generic infrastructure for orderings for leaf spaces.
Definition: leaforderingbase.hh:27
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:36
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)