You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
9.7 KiB
217 lines
9.7 KiB
2 years ago
|
#ifndef MEDUSA_BITS_OPERATORS_SHAPESTORAGE_HPP_
|
||
|
#define MEDUSA_BITS_OPERATORS_SHAPESTORAGE_HPP_
|
||
|
|
||
|
/**
|
||
|
* @file
|
||
|
* Implementations of the ShapeStorage interface.
|
||
|
*/
|
||
|
|
||
|
#include "ShapeStorage_fwd.hpp"
|
||
|
#include "printShapes.hpp"
|
||
|
|
||
|
namespace mm {
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
int ShapeStorage<Derived, vec_t, OpFamilies>::support(int node, int j) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= j && j < supportSize(node), "Support index %d out of range [0, %d).",
|
||
|
j, supportSize(node));
|
||
|
assert_msg(access(support_, node)[j] != -1, "Attempted access to shapes and support for node "
|
||
|
"%d, which were not computed.", node);
|
||
|
return access(support_, node)[j];
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
Eigen::Map<const Eigen::Matrix<int, Eigen::Dynamic, 1>>
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::support(int node) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(*access(support_, node) != -1, "Attempted access to shapes and support for node "
|
||
|
"%d, which were not computed.", node);
|
||
|
return {access(support_, node), supportSize(node)};
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
Range<int> ShapeStorage<Derived, vec_t, OpFamilies>::supportSizes() const {
|
||
|
Range<int> sizes(domain_size_, 0);
|
||
|
for (int i = 0; i < domain_size_; ++i) {
|
||
|
sizes[i] = supportSize(i);
|
||
|
}
|
||
|
return sizes;
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
Range<int> ShapeStorage<Derived, vec_t, OpFamilies>::supportSizesVec() const {
|
||
|
Range<int> sizes = supportSizes();
|
||
|
Range<int> res;
|
||
|
for (int d = 0; d < dim; ++d) res.append(sizes);
|
||
|
for (int& i : res) i *= dim;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
typename ShapeStorage<Derived, vec_t, OpFamilies>::scalar_t
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::laplace(int node, int j) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= j && j < supportSize(node), "Support index %d out of range [0, %d).",
|
||
|
j, supportSize(node));
|
||
|
return get<Lap<vec_t::dim>>(node, j);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
typename ShapeStorage<Derived, vec_t, OpFamilies>::scalar_t
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::d1(int var, int node, int j) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= j && j < supportSize(node), "Support index %d out of range [0, %d).",
|
||
|
j, supportSize(node));
|
||
|
assert_msg(0 <= var && var < dim, "Variable index %d out of bounds [%d, %d).", var, 0, dim);
|
||
|
return get<Der1s<dim>>(Der1s<dim>::index(Der1<dim>(var)), node, j);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
typename ShapeStorage<Derived, vec_t, OpFamilies>::scalar_t
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::d2(
|
||
|
int varmin, int varmax, int node, int j) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= j && j < supportSize(node), "Support index %d out of range [0, %d).",
|
||
|
j, supportSize(node));
|
||
|
assert_msg(0 <= varmin && varmin < dim,
|
||
|
"Variable varmin %d out of bounds [%d, %d).", varmin, 0, dim);
|
||
|
assert_msg(0 <= varmax && varmax < dim,
|
||
|
"Variable varmax %d out of bounds [%d, %d).", varmax, 0, dim);
|
||
|
assert_msg(varmin <= varmax, "Varmin (%d) must be smaller than varmax (%d).",
|
||
|
varmin, varmax);
|
||
|
return get<Der2s<dim>>(Der2s<dim>::index(Der2<dim>(varmin, varmax)), node, j);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
Eigen::Map<const Eigen::Matrix<typename ShapeStorage<Derived, vec_t, OpFamilies>::scalar_t,
|
||
|
Eigen::Dynamic, 1>>
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::laplace(int node) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
return getShape<Lap<vec_t::dim>>(node);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
Eigen::Map<const Eigen::Matrix<typename ShapeStorage<Derived, vec_t, OpFamilies>::scalar_t,
|
||
|
Eigen::Dynamic, 1>>
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::d1(int var, int node) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= var && var < dim, "Variable index %d out of bounds [%d, %d).", var, 0, dim);
|
||
|
return getShape<Der1s<dim>>(Der1s<dim>::index(Der1<dim>(var)), node);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
Eigen::Map<const Eigen::Matrix<typename ShapeStorage<Derived, vec_t, OpFamilies>::scalar_t,
|
||
|
Eigen::Dynamic, 1>>
|
||
|
ShapeStorage<Derived, vec_t, OpFamilies>::d2(int varmin, int varmax, int node) const {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= varmin && varmin < dim,
|
||
|
"Variable varmin %d out of bounds [%d, %d).", varmin, 0, dim);
|
||
|
assert_msg(0 <= varmax && varmax < dim,
|
||
|
"Variable varmax %d out of bounds [%d, %d).", varmax, 0, dim);
|
||
|
assert_msg(varmin <= varmax, "Varmin (%d) must be smaller than varmax (%d).",
|
||
|
varmin, varmax);
|
||
|
return getShape<Der2s<dim>>(Der2s<dim>::index(Der2<dim>(varmin, varmax)), node);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
void ShapeStorage<Derived, vec_t, OpFamilies>::setSupport(
|
||
|
int node, const std::vector<int>& support) {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(static_cast<int>(support.size()) == supportSize(node), "Support of unexpected "
|
||
|
"length %d, expected %d.", support.size(), supportSize(node));
|
||
|
std::memcpy(access(support_, node), support.data(),
|
||
|
support.size()*sizeof(int));
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
void ShapeStorage<Derived, vec_t, OpFamilies>::setLaplace(
|
||
|
int node, const Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>& shape) {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(shape.size() == supportSize(node), "Laplace shape of unexpected length %d, "
|
||
|
"expected %d.", shape.size(), supportSize(node));
|
||
|
setShape<Lap<vec_t::dim>>(node, shape);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
void ShapeStorage<Derived, vec_t, OpFamilies>::setD1(
|
||
|
int var, int node, const Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>& shape) {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= var && var < dim, "Variable index %d out of bounds [%d, %d).", var, 0, dim);
|
||
|
assert_msg(shape.size() == supportSize(node), "D1 shape of unexpected length %d, expected %d.",
|
||
|
shape.size(), supportSize(node));
|
||
|
setShape<Der1s<dim>>(var, node, shape);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
void ShapeStorage<Derived, vec_t, OpFamilies>::setD2(
|
||
|
int varmin, int varmax, int node, const Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>& shape) {
|
||
|
assert_msg(0 <= node && node <= domain_size_, "Node index %d out or range [0, %d).",
|
||
|
node, domain_size_);
|
||
|
assert_msg(0 <= varmin && varmin < dim,
|
||
|
"Variable varmin %d out of bounds [%d, %d).", varmin, 0, dim);
|
||
|
assert_msg(0 <= varmax && varmax < dim,
|
||
|
"Variable varmax %d out of bounds [%d, %d).", varmax, 0, dim);
|
||
|
assert_msg(varmin <= varmax, "Varmin (%d) must be smaller than varmax (%d).",
|
||
|
varmin, varmax);
|
||
|
assert_msg(shape.size() == supportSize(node), "D2 shape of unexpected length %d, expected %d.",
|
||
|
shape.size(), supportSize(node));
|
||
|
int idx = varmax*(varmax+1)/2 + varmin;
|
||
|
setShape<Der2s<dim>>(idx, node, shape);
|
||
|
}
|
||
|
|
||
|
/// Output basic info about this shape storage.
|
||
|
template <typename D, typename V, typename O>
|
||
|
std::ostream& operator<<(std::ostream& os, const ShapeStorage<D, V, O>& shapes) {
|
||
|
os << "Shape storage:\n";
|
||
|
return shapes_internal::printShapes(shapes, os);
|
||
|
}
|
||
|
|
||
|
template <typename Derived, typename vec_t, typename OpFamilies>
|
||
|
size_t ShapeStorage<Derived, vec_t, OpFamilies>::memoryUsed() const {
|
||
|
size_t size = sizeof(*this);
|
||
|
for (int i = 0; i < num_operators; ++i) {
|
||
|
size += mem_used(shapes_[i]);
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/// Contains a helper for resizing storage.
|
||
|
namespace resize_internal {
|
||
|
|
||
|
/// @cond
|
||
|
// A helper for resizing storage -- recursive case
|
||
|
template <typename OpFamilies, size_t i>
|
||
|
struct resize_storage_ {
|
||
|
template <typename Shapes>
|
||
|
static void resize(Shapes& shapes, int base_size) {
|
||
|
resize_storage_<OpFamilies, i-1>::template resize<Shapes>(shapes, base_size);
|
||
|
std::get<i-1>(shapes).resize(
|
||
|
base_size*std::tuple_element<i-1, OpFamilies>::type::size(), NaN);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// A helper for resizing storage -- base case
|
||
|
template <typename OpFamilies>
|
||
|
struct resize_storage_<OpFamilies, 0> {
|
||
|
template <typename Shapes> static void resize(Shapes&, int) {}
|
||
|
};
|
||
|
/// @endcond
|
||
|
|
||
|
} // namespace resize_internal
|
||
|
|
||
|
} // namespace mm
|
||
|
|
||
|
#endif // MEDUSA_BITS_OPERATORS_SHAPESTORAGE_HPP_
|