Line data Source code
1 : // This file is part of the Mamico project. For conditions of distribution 2 : // and use, please see the copyright notice in Mamico's main folder 3 : #pragma once 4 : 5 : #include "coupling/CouplingMDDefinitions.h" 6 : #include "coupling/datastructures/CouplingCell.h" 7 : #include "coupling/indexing/IndexingService.h" 8 : 9 : namespace coupling { 10 : namespace datastructures { 11 : template <class CellIndexT, unsigned int dim> class CellContainer; 12 : } // namespace datastructures 13 : } // namespace coupling 14 : 15 : /** 16 : * @brief provides access to the coupling cells. Base class for the class coupling::datastructures::LinkedCellContainer 17 : * 18 : * The CellContainer is intended to be used for a fixed indexing domain. Once created, it is assumed to hold all cells in that domain. For example, a 19 : * CellContainer created with template parameter I02 is expected to contain all cells that are accessible by iterating through I02. CellContainers do not 20 : * capture relevant cells automatically. It is the responsibility of the calling function to allocate the cells and populate the container completely before 21 : * using it. Due to this complete and contiguous nature of the datastructure, direct indexing is allowed, and the cell container is expected to start at 22 : * location 0 of the indexing domain it was initialized with. CellContainers contain pointers to coupling cells, the cells are not owned by the container, hence 23 : * the calling function must delete the cells later. 24 : * @tparam dim Number of dimensions; it can be 1, 2 or 3 25 : */ 26 56 : template <class CellIndexT, unsigned int dim> class coupling::datastructures::CellContainer { 27 : 28 : public: 29 32 : CellContainer() { _couplingCells.reserve(CellIndexT::linearNumberCellsInDomain); } 30 36 : CellContainer(std::vector<coupling::datastructures::CouplingCell<dim>*> couplingCells) { 31 36 : _couplingCells.reserve(CellIndexT::linearNumberCellsInDomain); 32 33476 : for (auto cell : couplingCells) { 33 33440 : *this << cell; 34 : } 35 36 : } 36 : 37 : /** Index based access, returns a pointer to the coupling cell 38 : * @param index index An index of type CellIndexT i.e. from the initializing subdomain 39 : * @return the pointer to the requested cell 40 : */ 41 4000 : coupling::datastructures::CouplingCell<dim>* operator[](CellIndexT index) const { 42 : #if (COUPLING_MD_ERROR == COUPLING_MD_YES) 43 4000 : if (_couplingCells.size() < CellIndexT::linearNumberCellsInDomain) { 44 0 : std::cout << "CellContainer<" << CellIndexT::TNAME << "," << dim << "> accessed but not full " << std::endl; 45 0 : std::exit(EXIT_FAILURE); 46 : } 47 : #endif 48 4000 : return _couplingCells[indexing::convertToScalar(index)]; 49 : } 50 : 51 : /** Adds a new coupling cell to the datastructure at the next index (will only work if the data structure is not yet full) 52 : * @param cell a pointer to the cell to be inserted 53 : */ 54 41440 : void operator<<(coupling::datastructures::CouplingCell<dim>* couplingCell) { 55 : #if (COUPLING_MD_ERROR == COUPLING_MD_YES) 56 41440 : if (_couplingCells.size() >= CellIndexT::linearNumberCellsInDomain) { 57 0 : std::cout << "CellContainer<" << CellIndexT::TNAME << "," << dim << "> can only hold " << CellIndexT::linearNumberCellsInDomain << " coupling cells!" 58 0 : << std::endl; 59 0 : std::exit(EXIT_FAILURE); 60 : } 61 : #endif 62 41440 : _couplingCells.push_back(couplingCell); 63 41440 : } 64 : 65 : /** 66 : * Returns size of the underlying container. 67 : * 68 : * This size is notably not the number of cells in the index domain. However, in practice the two numbers should be identical, as accessing contents of an 69 : * incomplete cotnainer is not allowed. 70 : * @return the number of cells stored currently 71 : */ 72 4 : unsigned int size() const { return _couplingCells.size(); } 73 : 74 : /** 75 : * @brief Provides iterator functionality (increment, access as <*cell, index> pair, equality) 76 : */ 77 56000 : class Iterator { 78 : public: 79 : using CouplingCellIterator = typename std::vector<coupling::datastructures::CouplingCell<dim>*>::const_iterator; 80 : 81 8064 : Iterator(CouplingCellIterator itCouplingCells, typename CellIndexT::IndexIterator itIdx) : _itCouplingCells(itCouplingCells), _itIdx(itIdx) {} 82 : 83 : /** 84 : * Iterator access, returning the data at the current iterator location 85 : * 86 : * @return a std::pair with the cell pointer and the index of the data that the iterator points to 87 : */ 88 38896 : const std::pair<coupling::datastructures::CouplingCell<dim>*, CellIndexT> operator*() const { return std::make_pair(*_itCouplingCells, *_itIdx); } 89 : 90 37440 : Iterator& operator++() { 91 9440 : ++_itCouplingCells; 92 37440 : ++_itIdx; 93 9440 : return *this; 94 : } 95 : 96 28000 : Iterator operator++(int) { 97 28000 : Iterator tmp = *this; 98 28000 : ++(*this); 99 28000 : return tmp; 100 : } 101 : 102 4000 : friend bool operator==(const Iterator& a, const Iterator& b) { return a._itCouplingCells == b._itCouplingCells; } 103 : 104 17456 : friend bool operator!=(const Iterator& a, const Iterator& b) { return !(a == b); } 105 : 106 : private: 107 : /**Iterator to underlying cell* vector */ 108 : CouplingCellIterator _itCouplingCells; 109 : 110 : /**Iterator over the index subdomain 111 : * 112 : * As the container spans the whole index subdomain, the iterators already available for this index domain can be reused, and incremented in lockstep with 113 : * the internal iterator for the vector 114 : */ 115 : typename CellIndexT::IndexIterator _itIdx; 116 : }; 117 : 118 : /** Provides pointer to beginning of iterator of this container */ 119 48 : Iterator begin() const { return Iterator(_couplingCells.begin(), CellIndexT::begin()); } 120 : 121 : /** Provides pointer to end of iterator of this container */ 122 8016 : Iterator end() const { return Iterator(_couplingCells.end(), CellIndexT::end()); } 123 : 124 : protected: 125 : /** 126 : * Holds pointers to all coupling cells. 127 : * This is used for interfacing to send-recv 128 : * operations. 129 : */ 130 : std::vector<coupling::datastructures::CouplingCell<dim>*> _couplingCells; 131 : };