#ifndef SRC_DATA_STRUCTURES_GLOBALFRICTIONCONTAINER_HH #define SRC_DATA_STRUCTURES_GLOBALFRICTIONCONTAINER_HH #include <vector> #include <cstddef> #include <list> #include <cassert> #include <memory> template <class BaseGlobalFriction, size_t depth> class GlobalFrictionContainer { public: using IndexObject = GlobalFrictionContainer<BaseGlobalFriction, depth-1>; using GlobalFriction = std::vector<IndexObject>; GlobalFrictionContainer() {} auto operator[](std::size_t i) -> IndexObject& { return globalFriction_[i]; } auto operator[](std::size_t i) const -> const IndexObject& { return globalFriction_[i]; } auto size() const -> size_t { return globalFriction_.size(); } void resize(std::list<size_t> list) { assert(list.size() <= depth); if (list.size() == 0) { globalFriction_.resize(0); } else { globalFriction_.resize(list.front()); list.pop_front(); for (size_t i=0; i<size(); i++) { globalFriction_[i].resize(list); } } } template <class VectorContainer> void updateAlpha(const VectorContainer& newAlpha) { assert(newAlpha.size() == size()); for (size_t i=0; i<size(); i++) { globalFriction_[i].updateAlpha(newAlpha[i]); } } auto globalFriction() -> GlobalFriction& { return globalFriction_; } auto globalFriction() const -> const GlobalFriction& { return globalFriction_; } private: GlobalFriction globalFriction_; }; template <class BaseGlobalFriction> class GlobalFrictionContainer<BaseGlobalFriction, 1> { public: using IndexObject = std::shared_ptr<BaseGlobalFriction>; using GlobalFriction = std::vector<IndexObject>; GlobalFrictionContainer() {} auto operator[](std::size_t i) -> IndexObject& { return globalFriction_[i]; } auto operator[](std::size_t i) const -> const IndexObject& { return globalFriction_[i]; } auto size() const -> size_t { return globalFriction_.size(); } void resize(std::list<size_t> newSize) { if (newSize.size() > 0) { globalFriction_.resize(newSize.front(), nullptr); } else { globalFriction_.resize(0); } } template <class Vector> void updateAlpha(const Vector& newAlpha) { for (size_t i=0; i<size(); i++) { globalFriction_[i]->updateAlpha(newAlpha); } } auto globalFriction() -> GlobalFriction& { return globalFriction_; } auto globalFriction() const -> const GlobalFriction& { return globalFriction_; } private: GlobalFriction globalFriction_; }; #endif