Alexandria 2.32.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
GridContainer.icpp
Go to the documentation of this file.
1
18
24
25#include "ElementsKernel/Exception.h"
27
28namespace Euclid {
29namespace GridContainer {
30
31template <typename GridCellManager, typename... AxesTypes>
37
38template <typename GridCellManager, typename... AxesTypes>
45
46template <typename GridCellManager, typename... AxesTypes>
47template <typename... Args>
55
56template <typename... AxesTypes>
58 size_t index) {
59 std::tuple<GridAxis<AxesTypes>...> result{original};
60 GridConstructionHelper<AxesTypes...>::template findAndFixAxis(result, axis, index, TemplateLoopCounter<0>{});
61 return result;
62}
63
64template <typename GridCellManager, typename... AxesTypes>
67 GridCellManagerTraits<GridCellManager>::factory(GridConstructionHelper<AxesTypes...>::getAxisIndexFactor(
68 m_axes, TemplateLoopCounter<sizeof...(AxesTypes) - 1>{}))} {}
69
70template <typename GridCellManager, typename... AxesTypes>
72 size_t axis, size_t index)
73 : m_axes{other.m_axes}
74 , m_axes_fixed{fixAxis(other.m_axes, axis, index)}
77 // Update the fixed indices
78 if (m_fixed_indices.find(axis) != m_fixed_indices.end()) {
79 throw Elements::Exception() << "Axis " << axis << " is already fixed";
80 }
81 m_fixed_indices[axis] = index;
82}
83
84template <typename GridCellManager, typename... AxesTypes>
86 GridContainer clone{m_axes};
87 std::copy(begin(), end(), std::begin(clone));
88 return clone;
89}
90
91template <typename GridCellManager, typename... AxesTypes>
92template <int I>
94 return std::get<I>(m_axes);
95}
96
97template <typename GridCellManager, typename... AxesTypes>
99 return std::tuple_size<decltype(m_axes_fixed)>::value;
100}
101
102template <typename GridCellManager, typename... AxesTypes>
103template <int I>
105 return std::get<I>(m_axes_fixed);
106}
107
108template <typename GridCellManager, typename... AxesTypes>
112
113template <typename GridCellManager, typename... AxesTypes>
115 iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
116 GridConstructionHelper<AxesTypes...>::fixIteratorAxes(result, m_fixed_indices, TemplateLoopCounter<0>{});
117 return result;
118}
119
120template <typename GridCellManager, typename... AxesTypes>
121auto GridContainer<GridCellManager, AxesTypes...>::begin() const -> const_iterator {
122 const_iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
124 return result;
125}
126
127template <typename GridCellManager, typename... AxesTypes>
133
134template <typename GridCellManager, typename... AxesTypes>
136 return iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
137}
138
139template <typename GridCellManager, typename... AxesTypes>
140auto GridContainer<GridCellManager, AxesTypes...>::end() const -> const_iterator {
141 return const_iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
142}
143
144template <typename GridCellManager, typename... AxesTypes>
147}
148
149template <typename GridCellManager, typename... AxesTypes>
151 return m_index_helper_fixed.m_axes_index_factors.back();
152}
153
154template <typename GridCellManager, typename... AxesTypes>
156 decltype(std::declval<GridAxis<AxesTypes>>().size())... indices) const -> const reference_type {
157 size_t total_index = m_index_helper.totalIndex(indices...);
158 // If we have fixed axes we need to move the index accordingly
159 for (auto& pair : m_fixed_indices) {
160 total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
161 }
162 return (*m_cell_manager)[total_index];
163}
164
165template <typename GridCellManager, typename... AxesTypes>
167 decltype(std::declval<GridAxis<AxesTypes>>().size())... indices) -> reference_type {
168 size_t total_index = m_index_helper.totalIndex(indices...);
169 // If we have fixed axes we need to move the index accordingly
170 for (auto& pair : m_fixed_indices) {
171 total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
172 }
173 return (*m_cell_manager)[total_index];
174}
175
176template <typename GridCellManager, typename... AxesTypes>
178 decltype(std::declval<GridAxis<AxesTypes>>().size())... indices) const -> const reference_type {
179 return const_cast<GridContainer*>(this)->at(indices...);
180}
181
182template <typename GridCellManager, typename... AxesTypes>
184 -> reference_type {
185 // First make a check that all the fixed axes are zero
186 m_index_helper.checkAllFixedAreZero(m_fixed_indices, indices...);
187 size_t total_index = m_index_helper.totalIndexChecked(indices...);
188 // If we have fixed axes we need to move the index accordingly
189 for (auto& pair : m_fixed_indices) {
190 total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
191 }
192 return (*m_cell_manager)[total_index];
194
195template <std::size_t I>
197 template <typename>
199
200 template <typename... AxesType>
204 getIndex(coords, axes, index);
205 return index;
206 }
207
208 template <typename IndexTuple, typename... AxesType>
209 static void getIndex(const std::tuple<AxesType...>& coords, const std::tuple<GridAxis<AxesType>...>& axes,
210 IndexTuple& index) {
211 auto& axn = std::get<I>(axes);
212 std::get<I>(index) = axn.infimum(std::get<I>(coords)) - axn.begin();
213 InfimumHelper<I - 1>::getIndex(coords, axes, index);
215};
216
217template <>
218struct InfimumHelper<0> {
219 template <typename>
221
222 template <typename... AxesType>
224 const std::tuple<GridAxis<AxesType>...>& axes) {
225 auto i0 = std::get<0>(axes).infimum(std::get<0>(coords));
226 return std::make_tuple(i0);
227 }
228
229 template <typename IndexTuple, typename... AxesType>
230 static void getIndex(const std::tuple<AxesType...>& coords, const std::tuple<GridAxis<AxesType>...>& axes,
231 IndexTuple& index) {
232 auto& ax0 = std::get<0>(axes);
233 std::get<0>(index) = ax0.infimum(std::get<0>(coords)) - ax0.begin();
234 }
235};
236
237template <typename GridCellManager, typename... AxesTypes>
238auto GridContainer<GridCellManager, AxesTypes...>::infimum(const AxesTypes... coordinates) const
239 -> std::tuple<decltype(std::declval<GridAxis<AxesTypes>>().size())...> {
240 return infimum(std::make_tuple(coordinates...));
241}
242
243template <typename GridCellManager, typename... AxesTypes>
245 -> std::tuple<decltype(std::declval<GridAxis<AxesTypes>>().size())...> {
246 return InfimumHelper<sizeof...(AxesTypes) - 1>::getIndex(coords, m_axes);
247}
248
249template <typename GridCellManager, typename... AxesTypes>
250template <int I>
251GridContainer<GridCellManager, AxesTypes...>
253 if (index >= getOriginalAxis<I>().size()) {
254 throw Elements::Exception() << "Index (" << index << ") out of axis " << getOriginalAxis<I>().name() << " size ("
255 << getOriginalAxis<I>().size() << ")";
256 }
257 return GridContainer<GridCellManager, AxesTypes...>(*this, I, index);
258}
259
260template <typename GridCellManager, typename... AxesTypes>
261template <int I>
262const GridContainer<GridCellManager, AxesTypes...>
264 return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByIndex<I>(index);
265}
266
267template <typename GridCellManager, typename... AxesTypes>
268template <int I>
269GridContainer<GridCellManager, AxesTypes...>
271 auto& axis = getOriginalAxis<I>();
272 auto found_axis = std::find(axis.begin(), axis.end(), value);
273 if (found_axis == axis.end()) {
274 throw Elements::Exception() << "Failed to fix axis " << getOriginalAxis<I>().name() << " (given value not found)";
275 }
276 return GridContainer<GridCellManager, AxesTypes...>(*this, I, found_axis - axis.begin());
277}
279template <typename GridCellManager, typename... AxesTypes>
280template <int I>
281const GridContainer<GridCellManager, AxesTypes...>
283 return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByValue<I>(value);
284}
285
286} // end of namespace GridContainer
287} // end of namespace Euclid
T begin(T... args)
Provides information related with an axis of a GridContainer.
Definition GridAxis.h:49
GridContainer construction helper class.
static size_t getAxisIndexFactor(const std::tuple< GridAxis< Axes >... > &axes, const TemplateLoopCounter< I > &)
Returns the index factor of an axis.
static void fixIteratorAxes(IterType &iter, std::map< size_t, size_t > fix_indices, const TemplateLoopCounter< I > &)
Representation of a multi-dimensional grid which contains axis information.
const_iterator cend()
Returns a constant iterator to the cell after the last of the grid.
std::shared_ptr< GridCellManager > m_cell_manager
A pointer to the data of the grid.
GridContainer copy() const
But if needed be, allow explicit copies.
const GridAxis< axis_type< I > > & getOriginalAxis() const
GridContainer< GridCellManager, AxesTypes... > fixAxisByValue(const axis_type< I > &value)
Returns a slice of the grid based on an axis value.
iter< cell_type const, pointer_type const, reference_type const > const_iterator
std::tuple< GridAxis< AxesTypes >... > m_axes
A tuple containing the axes of the grid.
std::tuple< decltype(std::declval< GridAxis< AxesTypes > >().size())... > infimum(const AxesTypes... coordinates) const
Returns the grid indexes to the greatest knot less or equal to the given coordinates.
const std::tuple< GridAxis< AxesTypes >... > & getAxesTuple() const
Returns a tuple containing the information of all the grid axes.
const GridAxis< axis_type< I > > & getAxis() const
decltype(ref_test< GridCellManagerTraits< GridCellManager > >(nullptr)) reference_type
const reference_type at(decltype(std::declval< GridAxis< AxesTypes > >().size())... indices) const
static constexpr size_t axisNumber()
Returns the number of axes of the grid (dimensionality).
std::tuple< GridAxis< AxesTypes >... > m_axes_fixed
a tuple containing the original axes of the full grid, if this grid is a slice
iterator end()
Returns an iterator to the cell after the last of the grid.
size_t size() const
Returns the total number of cells of the grid.
typename std::tuple_element< I, std::tuple< AxesTypes... > >::type axis_type
const_iterator cbegin()
Returns a constant iterator to the first cell of the grid.
GridContainer(GridAxis< AxesTypes >... axes)
Constructs a GridContainer with the given axes.
std::map< size_t, size_t > m_fixed_indices
A map containing the axes which have been fixed, if this grid is a slice.
GridContainer< GridCellManager, AxesTypes... > fixAxisByIndex(size_t index)
Returns a slice of the grid based on an axis index.
const reference_type operator()(decltype(std::declval< GridAxis< AxesTypes > >().size())... indices) const
iterator begin()
Returns an iterator to the first cell of the grid.
GridIndexHelper< AxesTypes... > m_index_helper_fixed
a helper class for calculations of the original axes indices
T copy(T... args)
T declval(T... args)
T find(T... args)
T forward(T... args)
T make_tuple(T... args)
std::tuple< GridAxis< AxesTypes >... > fixAxis(const std::tuple< GridAxis< AxesTypes >... > &original, size_t axis, size_t index)
STL namespace.
Class used by the GridContainer to access the different CellManagers.
static std::unique_ptr< GridCellManager > factory(size_t size)
static iterator end(GridCellManager &cell_manager)
static iterator begin(GridCellManager &cell_manager)
static void getIndex(const std::tuple< AxesType... > &coords, const std::tuple< GridAxis< AxesType >... > &axes, IndexTuple &index)
static std::tuple< std::size_t > getIndex(const std::tuple< AxesType... > &coords, const std::tuple< GridAxis< AxesType >... > &axes)
static void getIndex(const std::tuple< AxesType... > &coords, const std::tuple< GridAxis< AxesType >... > &axes, IndexTuple &index)
static std::tuple< Index< AxesType >... > getIndex(const std::tuple< AxesType... > &coords, const std::tuple< GridAxis< AxesType >... > &axes)