diff --git a/src/common/field_collection_global.hh b/src/common/field_collection_global.hh index 53787a4..a82ffe1 100644 --- a/src/common/field_collection_global.hh +++ b/src/common/field_collection_global.hh @@ -1,191 +1,204 @@ /** * @file field_collection_global.hh * * @author Till Junge * * @date 05 Nov 2017 * * @brief FieldCollection base-class for global fields * * Copyright © 2017 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef FIELD_COLLECTION_GLOBAL_H #define FIELD_COLLECTION_GLOBAL_H #include "common/field_collection_base.hh" #include "common/ccoord_operations.hh" namespace muSpectre { /* ---------------------------------------------------------------------- */ /** `GlobalFieldCollection` derives from `FieldCollectionBase` and stores * global fields that live throughout the whole computational domain, i.e. * are defined for each pixel. */ template class GlobalFieldCollection: public FieldCollectionBase> { public: using Parent = FieldCollectionBase >; //!< base class using Ccoord = typename Parent::Ccoord; //!< cell coordinates type using Field_p = typename Parent::Field_p; //!< spatial coordinates type //! iterator over all pixels contained it the collection using iterator = typename CcoordOps::Pixels::iterator; //! Default constructor GlobalFieldCollection(); //! Copy constructor GlobalFieldCollection(const GlobalFieldCollection &other) = delete; //! Move constructor GlobalFieldCollection (GlobalFieldCollection &&other) = default; //! Destructor virtual ~GlobalFieldCollection() = default; //! Copy assignment operator GlobalFieldCollection& operator=(const GlobalFieldCollection &other) = delete; //! Move assignment operator GlobalFieldCollection& operator=(GlobalFieldCollection &&other) = default; /** allocate memory, etc. At this point, the collection is informed aboud the size and shape of the domain (through the sizes parameter). The job of initialise is to make sure that all fields are either of size 0, in which case they need to be allocated, or are of the same size as the product of 'sizes' (if standard strides apply) any field of a different size is wrong. TODO: check whether it makes sense to put a runtime check here **/ - inline void initialise(Ccoord sizes); + inline void initialise(Ccoord sizes, Ccoord locations); - //! return the pixel sizes + //! return subdomain resolutions inline const Ccoord & get_sizes() const; + //! return subdomain locations + inline const Ccoord & get_locations() const; //! returns the linear index corresponding to cell coordinates template inline size_t get_index(CcoordRef && ccoord) const; //! returns the cell coordinates corresponding to a linear index inline Ccoord get_ccoord(size_t index) const; inline iterator begin(); //!< returns iterator to first pixel inline iterator end(); //!< returns iterator past the last pixel //! return spatial dimension (template parameter) static constexpr inline Dim_t spatial_dim() {return DimS;} protected: //! number of discretisation cells in each of the DimS spatial directions Ccoord sizes{}; + Ccoord locations{}; CcoordOps::Pixels pixels{}; //!< helper to iterate over the grid private: }; /* ---------------------------------------------------------------------- */ template GlobalFieldCollection::GlobalFieldCollection() :Parent() {} /* ---------------------------------------------------------------------- */ template void GlobalFieldCollection:: - initialise(Ccoord sizes) { + initialise(Ccoord sizes, Ccoord locations) { if (this->is_initialised) { throw std::runtime_error("double initialisation"); } - this->pixels = CcoordOps::Pixels(sizes); + this->pixels = CcoordOps::Pixels(sizes, locations); this->size_ = CcoordOps::get_size(sizes); this->sizes = sizes; + this->locations = locations; std::for_each(std::begin(this->fields), std::end(this->fields), [this](auto && item) { auto && field = *item.second; const auto field_size = field.size(); if (field_size == 0) { field.resize(this->size()); } else if (field_size != this->size()) { std::stringstream err_stream; err_stream << "Field '" << field.get_name() << "' contains " << field_size << " entries, but the field collection " << "has " << this->size() << " pixels"; throw FieldCollectionError(err_stream.str()); } }); this->is_initialised = true; } //----------------------------------------------------------------------------// - //! return the pixel sizes + //! return subdomain resolutions template const typename GlobalFieldCollection::Ccoord & GlobalFieldCollection::get_sizes() const { return this->sizes; } + //----------------------------------------------------------------------------// + //! return subdomain locations + template + const typename GlobalFieldCollection::Ccoord & + GlobalFieldCollection::get_locations() const { + return this->locations; + } + //----------------------------------------------------------------------------// //! returns the cell coordinates corresponding to a linear index template typename GlobalFieldCollection::Ccoord GlobalFieldCollection::get_ccoord(size_t index) const { - return CcoordOps::get_ccoord(this->get_sizes(), std::move(index)); + return CcoordOps::get_ccoord(this->get_sizes(), this->get_locations(), + std::move(index)); } /* ---------------------------------------------------------------------- */ template typename GlobalFieldCollection::iterator GlobalFieldCollection::begin() { return this->pixels.begin(); } /* ---------------------------------------------------------------------- */ template typename GlobalFieldCollection::iterator GlobalFieldCollection::end() { return this->pixels.end(); } //----------------------------------------------------------------------------// //! returns the linear index corresponding to cell coordinates template template size_t GlobalFieldCollection::get_index(CcoordRef && ccoord) const { static_assert(std::is_same< Ccoord, std::remove_const_t< std::remove_reference_t>>::value, "can only be called with values or references of Ccoord"); return CcoordOps::get_index(this->get_sizes(), std::forward(ccoord)); } } // muSpectre #endif /* FIELD_COLLECTION_GLOBAL_H */