Page MenuHomec4science

grid_view.hh
No OneTemporary

File Metadata

Created
Sat, May 4, 04:26

grid_view.hh

/*
* SPDX-License-Indentifier: AGPL-3.0-or-later
*
* Copyright (©) 2016-2023 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
* Copyright (©) 2020-2023 Lucas Frérot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef GRID_VIEW_HH
#define GRID_VIEW_HH
/* -------------------------------------------------------------------------- */
#include "grid.hh"
#include "tamaas.hh"
#include <vector>
/* -------------------------------------------------------------------------- */
namespace tamaas {
/* -------------------------------------------------------------------------- */
/**
* @brief View type on grid
* This is a view on a *contiguous* chunk of data defined by a grid
*/
template <template <typename, UInt> class Base, typename T, UInt base_dim,
UInt dim>
class GridView : public Base<T, dim> {
public:
using iterator = typename Base<T, dim>::iterator;
using const_iterator = typename Base<T, dim>::const_iterator;
using value_type = typename Base<T, dim>::value_type;
using referecence = typename Base<T, dim>::reference;
public:
/// Constructor
GridView(GridBase<typename Base<T, dim>::value_type>& grid_base,
const std::vector<UInt>& multi_index, Int component = -1);
/// Move constructor
GridView(GridView&& o) noexcept
: Base<T, dim>(std::forward<Base<T, dim>>(o)),
grid(std::exchange(o.grid, nullptr)) {}
/// Destructor
~GridView() override = default;
UInt dataSize() const override { return this->computeSize(); }
// Forbid these methods for obvious reasons
void reserve(UInt size) = delete;
void resize(UInt size) = delete;
/// Iterators
iterator begin(UInt /*n*/ = 1) override {
return iterator(this->getInternalData(), this->strides.back());
}
iterator end(UInt /*n*/ = 1) override {
return iterator(this->getInternalData() +
this->dataSize() * this->strides.back(),
this->strides.back());
}
const_iterator begin(UInt /*n*/ = 1) const override {
return const_iterator(this->getInternalData(), this->strides.back());
}
const_iterator end(UInt /*n*/ = 1) const override {
return const_iterator(this->getInternalData() +
this->dataSize() * this->strides.back(),
this->strides.back());
}
protected:
Base<T, base_dim>* grid;
};
/* -------------------------------------------------------------------------- */
template <template <typename, UInt> class Base, typename T, UInt base_dim,
typename... Args>
GridView<Base, T, base_dim, base_dim - sizeof...(Args)>
make_view(Base<T, base_dim>& base, Args... indices) {
std::vector<UInt> multi_index = {static_cast<UInt>(indices)...};
return GridView<Base, T, base_dim, base_dim - sizeof...(Args)>(base,
multi_index);
}
template <template <typename, UInt> class Base, typename T, UInt base_dim>
GridView<Base, T, base_dim, base_dim>
make_component_view(Base<T, base_dim>& base, UInt component) {
std::vector<UInt> multi_index{};
return GridView<Base, T, base_dim, base_dim>(base, multi_index, component);
}
/* -------------------------------------------------------------------------- */
/* Template implementation */
/* -------------------------------------------------------------------------- */
template <template <typename, UInt> class Base, typename T, UInt base_dim,
UInt dim>
GridView<Base, T, base_dim, dim>::GridView(
GridBase<typename Base<T, dim>::value_type>& grid_base,
const std::vector<UInt>& multi_index, Int component)
: Base<T, dim>(), grid(nullptr) {
// static_assert(base_dim >= dim,
// "view dimension must be >= than the base class");
// Checking view type
grid = dynamic_cast<Base<T, base_dim>*>(&grid_base);
if (!grid)
TAMAAS_EXCEPTION("given base type is incompatible with view");
constexpr Int dim_offset = Int{base_dim} - Int{dim};
if (dim_offset >= 0 and dim_offset != static_cast<Int>(multi_index.size()))
TAMAAS_EXCEPTION("Number of blocked indices ("
<< multi_index.size()
<< ") does not match view dimension (" << base_dim
<< " -> " << dim << ")");
std::copy(grid->sizes().begin() + std::max(dim_offset, Int{0}),
grid->sizes().end(),
this->n.begin() + std::max(-dim_offset, Int{0}));
std::copy(grid->getStrides().begin() + std::max(dim_offset, Int{0}),
grid->getStrides().end(),
this->strides.begin() + std::max(-dim_offset, Int{0}));
if (dim_offset < 0)
std::fill_n(this->n.begin(), -dim_offset, 1);
if (component == -1) { // view all components
this->nb_components = grid->getNbComponents();
component = 0;
} else if (component >= 0 and
component < static_cast<Int>(
grid->getNbComponents())) { // view one component
this->nb_components = 1;
this->strides.back() = grid->getNbComponents();
} else
TAMAAS_EXCEPTION("Components out of bounds for view");
auto offset = std::inner_product(multi_index.begin(), multi_index.end(),
grid->getStrides().begin(), component);
this->data.wrap(grid->getInternalData() + offset, grid->dataSize() - offset);
}
/* -------------------------------------------------------------------------- */
} // namespace tamaas
#endif // GRID_VIEW_HH

Event Timeline