LCOV - code coverage report
Current view: top level - coupling/datastructures - FlexibleCellContainer.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 30 100.0 %
Date: 2025-06-25 11:26:37 Functions: 4 4 100.0 %

          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/datastructures/FlexibleCellContainer.h"
       8             : #include "coupling/indexing/IndexingService.h"
       9             : #include <cstddef>
      10             : #include <iostream>
      11             : #include <iterator>
      12             : #include <utility>
      13             : #include <vector>
      14             : 
      15             : namespace coupling {
      16             : namespace datastructures {
      17             : template <unsigned int dim> class FlexibleCellContainer;
      18             : }
      19             : } // namespace coupling
      20             : 
      21             : /**
      22             :  *      @brief provides access to coupling cells, which may belong to different indexing domains
      23             :  *
      24             :  * The FlexibleCellContainer is intended for use in cell domains which do not neatly correspond to a predefined indexing domain. For example, a CellContainer
      25             :  * cannot store cells in the macro2md overlap layers, and hence a FlexibleCellContainer is needed. Due to the "holes" expected due to the
      26             :  * non-contiguous nature of this container, index-based access is not possible or expected.
      27             :  *      @tparam dim Number of dimensions; it can be 1, 2 or 3
      28             :  */
      29             : 
      30          36 : template <unsigned int dim> class coupling::datastructures::FlexibleCellContainer {
      31             : public:
      32           8 :   FlexibleCellContainer() {}
      33          36 :   FlexibleCellContainer(std::vector<coupling::datastructures::CouplingCell<dim>*> couplingCells, std::vector<I01> idxs) {
      34             : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
      35             :     if (couplingCells.size() != idxs.size()) {
      36             :       std::cout << "ERROR size of index vector and coupling cell vector sent to FlexibleCellContainer constructor do not match";
      37             :       exit(EXIT_FAILURE);
      38             :     }
      39             : #endif
      40          36 :     _couplingCells.reserve(couplingCells.size());
      41          36 :     _idxs.reserve(idxs.size());
      42         396 :     for (std::size_t i = 0; i < couplingCells.size(); ++i) {
      43         360 :       _couplingCells.push_back(couplingCells[i]);
      44         360 :       _idxs.push_back(idxs[i]);
      45             :     }
      46          36 :   }
      47             : 
      48             :   template <class Container_T> FlexibleCellContainer(Container_T cells) {
      49             :     if constexpr (std::is_same_v<Container_T, FlexibleCellContainer>) {
      50             :       _idxs = cells._idxs;
      51             :       _couplingCells = cells._couplingCells;
      52             :     } else {
      53             :       auto numCells = cells.size();
      54             :       _idxs.reserve(numCells);
      55             :       _couplingCells.reserve(numCells);
      56             :       for (auto pair : cells)
      57             :         *this << pair;
      58             :     }
      59             :   }
      60             : 
      61             :   /** Adds a new coupling cell to the datastructure at the next index
      62             :    * @param cell a pointer to the cell to be inserted
      63             :    */
      64          44 :   void operator<<(std::pair<coupling::datastructures::CouplingCell<dim>*, I01> pair) {
      65          44 :     I01 idx;
      66             :     coupling::datastructures::CouplingCell<dim>* couplingCell;
      67          44 :     std::tie(couplingCell, idx) = pair;
      68          44 :     _couplingCells.push_back(couplingCell);
      69          44 :     _idxs.push_back(idx);
      70          44 :   }
      71             : 
      72             :   /**
      73             :    * Returns size of the underlying container.
      74             :    *
      75             :    * The number of indices stored should be equal to the number of cells stored, hence returning either is okay
      76             :    * @return the number of cells stored currently
      77             :    */
      78           8 :   unsigned int size() const { return _couplingCells.size(); }
      79             : 
      80             :   /**
      81             :    * @brief Provides iterator functionality (increment, access as <*cell, index> pair, equality)
      82             :    */
      83             :   class Iterator {
      84             :   public:
      85             :     using CouplingCellIterator = typename std::vector<coupling::datastructures::CouplingCell<dim>*>::const_iterator;
      86             :     using IndexIterator = std::vector<I01>::const_iterator;
      87             : 
      88         140 :     Iterator(CouplingCellIterator itCouplingCells, IndexIterator itIdxs) : _itCouplingCells(itCouplingCells), _itIdxs(itIdxs) {}
      89             : 
      90             :     /**
      91             :      * Iterator access, returning the data at the current iterator location
      92             :      *
      93             :      * @return a std::pair with the cell pointer and the index of the data that the iterator points to
      94             :      */
      95         408 :     const std::pair<coupling::datastructures::CouplingCell<dim>*, I01> operator*() const { return std::make_pair(*_itCouplingCells, *_itIdxs); }
      96             : 
      97         320 :     Iterator& operator++() {
      98         120 :       ++_itCouplingCells;
      99         320 :       ++_itIdxs;
     100         120 :       return *this;
     101             :     }
     102             : 
     103         200 :     Iterator operator++(int) {
     104         200 :       Iterator tmp = *this;
     105         200 :       ++(*this);
     106         200 :       return tmp;
     107             :     }
     108             : 
     109          56 :     friend bool operator==(const Iterator& a, const Iterator& b) { return a._itCouplingCells == b._itCouplingCells && a._itIdxs == b._itIdxs; }
     110             : 
     111         232 :     friend bool operator!=(const Iterator& a, const Iterator& b) { return !(a == b); }
     112             : 
     113             :   private:
     114             :     /**Iterator to underlying cell* vector */
     115             :     CouplingCellIterator _itCouplingCells;
     116             : 
     117             :     /**Iterator to underlying index vector */
     118             :     IndexIterator _itIdxs;
     119             :   };
     120             :   /** Provides pointer to beginning of iterator of this container */
     121          44 :   Iterator begin() const { return Iterator(_couplingCells.begin(), _idxs.begin()); }
     122             : 
     123             :   /** Provides pointer to end of iterator of this container */
     124          96 :   Iterator end() const { return Iterator(_couplingCells.end(), _idxs.end()); }
     125             : 
     126             : private:
     127             :   /**Vector to store pointers to cells */
     128             :   std::vector<coupling::datastructures::CouplingCell<dim>*> _couplingCells;
     129             : 
     130             :   /**Vector to store indices corresponding to cells in container
     131             :    * Since the cells can be part of any domain, they're stores as I01 (global noghost) type.
     132             :    */
     133             :   std::vector<I01> _idxs;
     134             : };

Generated by: LCOV version 1.14