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 : };
|