LCOV - code coverage report
Current view: top level - coupling/datastructures - CellContainer.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 35 85.7 %
Date: 2025-06-25 11:26:37 Functions: 12 19 63.2 %

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

Generated by: LCOV version 1.14