#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace AMDiS { /// \brief The basic container that stores a base vector and a corresponding basis /** * Basis implementation of DOFVector, i.e. a vector storing all the * assembled Operators indexed with DOF indices. The vector data is associated * to a global basis. * * \tparam B Basis of the vector * \tparam Backend A linear algebra backend implementing the storage and operations. **/ template class DOFVectorBase : public DOFVectorInterface { using Self = DOFVectorBase; public: /// The type of the functionspace basis associated to this vector using Basis = BasisType; using LocalView = typename Basis::LocalView; using Element = typename LocalView::Element; using Geometry = typename Element::Geometry; /// The index/size - type using size_type = typename BasisType::size_type; /// The type of the elements of the DOFVector using value_type = typename Backend::value_type; /// The type of the data vector used in the backend using BaseVector = typename Backend::BaseVector; using ElementVector = Dune::DynamicVector; /// Defines an interface to transfer the data during grid adaption using DataTransfer = DataTransferInterface; /// A creator for a concrete data transfer object, depending on \ref DataTransferOperation using DataTransferFactory = AMDiS::DataTransferFactory; public: /// Constructor. Constructs new BaseVector. DOFVectorBase(BasisType const& basis, DataTransferOperation op = NO_OPERATION) : basis_(&basis) , dataTransfer_(DataTransferFactory::create(op, basis)) { compress(); GridTransferManager::attach(*this); operators_.init(basis); } /// Copy constructor DOFVectorBase(Self const& that) : basis_(that.basis_) , backend_(that.backend_) , elementVector_(that.elementVector_) , operators_(that.operators_) , dataTransfer_(that.dataTransfer_) { GridTransferManager::attach(*this); } /// Move constructor DOFVectorBase(Self&& that) : basis_(std::move(that.basis_)) , backend_(std::move(that.backend_)) , elementVector_(std::move(that.elementVector_)) , operators_(std::move(that.operators_)) , dataTransfer_(std::move(that.dataTransfer_)) { GridTransferManager::attach(*this); } /// Destructor ~DOFVectorBase() override { GridTransferManager::detach(*this); } /// Copy assignment operator Self& operator=(Self const& that) { GridTransferManager::detach(*this); basis_ = that.basis_; backend_.resize(that.size()); backend_ = that.backend_; dataTransfer_ = that.dataTransfer_; GridTransferManager::attach(*this); return *this; } /// Move assignment Self& operator=(Self&& that) = default; /// Sets each DOFVector to the scalar \p value. template ::value, int> = 0> Self& operator=(Number value) { backend_.set(value); return *this; } /// Return the basis \ref basis_ associated to the vector Basis const& basis() const { return *basis_; } /// Return the data-vector BaseVector const& vector() const { return backend_.vector(); } /// Return the data-vector BaseVector& vector() { return backend_.vector(); } /// Return the size of the \ref basis size_type size() const { return basis_->dimension(); } void resize(Dune::Functions::SizeInfo const& s) { backend_.resize(size_type(s)); } /// Resize the \ref vector to the size of the \ref basis and set to zero void compress() override { if (size_type(backend_.size()) != size()) { backend_.resize(size()); backend_.set(0); } } /// Access the entry \p idx of the \ref vector with read-access. template auto const& operator[](Index idx) const { size_type i = flatMultiIndex(idx); return backend_[i]; } /// Access the entry \p idx of the \ref vector with write-access. template auto& operator[](Index idx) { size_type i = flatMultiIndex(idx); return backend_[i]; } void init(bool asmVector); void finish(bool asmVector); /// Insert a block of values into the matrix (add to existing values) void insert(LocalView const& localView, ElementVector const& elementVector); /// Associate a local operator with this DOFVector template void addOperator(ContextTag contextTag, Operator const& preOp, TreePath path = {}); /// Assemble the vector operators on the bound element. void assemble(LocalView const& localView); /// Assemble all vector operators void assemble(); /// Return the associated DataTransfer object DataTransfer const& dataTransfer() const { return *dataTransfer_; } /// Return the associated DataTransfer object DataTransfer& dataTransfer() { return *dataTransfer_; } /// Create a new DataTransfer object based on the operation type void setDataTransfer(DataTransferOperation op) { dataTransfer_ = DataTransferFactory::create(op, this->basis()); } /// Assign the DataTransfer object void setDataTransfer(std::shared_ptr const& dataTransfer) { dataTransfer_ = dataTransfer; } /// Implementation of \ref DOFVectorInterface::preAdapt void preAdapt(bool mightCoarsen) override { dataTransfer_->preAdapt(*this, mightCoarsen); } /// Implementation of \ref DOFVectorInterface::postAdapt void postAdapt(bool refined) override { dataTransfer_->postAdapt(*this, refined); } private: /// The finite element space / basis associated with the data vector Basis const* basis_; /// Data backend Backend backend_; /// Dense vector to store coefficients during \ref assemble() ElementVector elementVector_; /// List of operators associated to nodes VectorOperators operators_; /// Data interpolation when the grid changes std::shared_ptr dataTransfer_; }; } // end namespace AMDiS #include "DOFVectorBase.inc.hpp"