mmiterator.hh 7.57 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1 2 3 4 5 6
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_MULTIMESH_ITERATOR_HH
#define DUNE_MULTIMESH_ITERATOR_HH

#include <numeric>
7
#include <vector>
Praetorius, Simon's avatar
Praetorius, Simon committed
8 9 10 11

#include <dune/common/iteratorfacades.hh>
#include <dune/grid/common/gridenums.hh>

Praetorius, Simon's avatar
Praetorius, Simon committed
12
#include "mmentity.hh"
13
#include "mmhierarchiciterator.hh"
14
#include "mmiteratorbase.hh"
Praetorius, Simon's avatar
Praetorius, Simon committed
15 16 17

namespace Dune
{
18
  template <int codim, PartitionIteratorType pitype, class HostGrid>
19
  class MultiMeshLevelIterator : public DummyIterator
Praetorius, Simon's avatar
Praetorius, Simon committed
20
  {
21
    using DummyIterator::DummyIterator;
Praetorius, Simon's avatar
Praetorius, Simon committed
22 23
  };

24
  template <PartitionIteratorType pitype, class HostGrid>
25 26
  class MultiMeshLevelIterator<0,pitype,HostGrid>
      : public MultiMeshIteratorBase<pitype,HostGrid,MultiMeshLevelIterator<0,pitype,HostGrid>>
Praetorius, Simon's avatar
Praetorius, Simon committed
27
  {
28 29
    using Self = MultiMeshLevelIterator;
    using Super = MultiMeshIteratorBase<pitype,HostGrid,Self>;
30
    using HostEntity = typename HostGrid::template Codim<0>::Entity;
31
    using EntityTest = typename Super::EntityTest;
Praetorius, Simon's avatar
Praetorius, Simon committed
32 33

  public:
34
    // Level iterator
35
    template <class GridImp>
36 37 38
    MultiMeshLevelIterator (tag::begin_iterator, const GridImp* multiMesh, int level)
      : Super{tag::begin_iterator{}, multiMesh}
      , incrementAllowed_(multiMesh->size(), true)
39
      , contains_(multiMesh->size(), EntityTest{[level](const HostEntity& entity) { return entity.level() == level; }})
40
      , multiEntity_(multiMesh->size())
Praetorius, Simon's avatar
Praetorius, Simon committed
41
    {
42
      this->initialIncrement();
Praetorius, Simon's avatar
Praetorius, Simon committed
43 44
    }

45
    // End iterator
46
    template <class GridImp>
47 48 49 50 51
    MultiMeshLevelIterator (tag::end_iterator, const GridImp* multiMesh, int level = -1)
      : Super{tag::end_iterator{}, multiMesh}
    {}

    void initialIncrement_impl ()
Praetorius, Simon's avatar
Praetorius, Simon committed
52
    {
53 54
      for (std::size_t i = 0; i < this->size(); ++i)
        this->initialIncrement(i);
Praetorius, Simon's avatar
Praetorius, Simon committed
55 56
    }

57 58 59 60
    void increment_impl ()
    {
      for (std::size_t i = 0; i < this->size(); ++i)
        incrementAllowed_[i] = this->incrementAllowed(i);
Praetorius, Simon's avatar
Praetorius, Simon committed
61

62 63 64 65 66
      for (std::size_t i = 0; i < this->size(); ++i) {
        if (incrementAllowed_[i])
          this->increment(i);
      }
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
67

68
    const MultiEntity<HostGrid>& dereference_impl () const
69
    {
70 71 72 73 74 75 76
      // update entries in multiEntity that have changed
      for (std::size_t i = 0; i <  this->size(); ++i) {
        if (incrementAllowed_[i])
          multiEntity_[i] = this->dereference(i);
      }
      return multiEntity_;
    }
77

78 79 80
    bool levelReached_impl (std::size_t i, const HostEntity& entity) const
    {
      return contains_[i](entity) || entity.isLeaf();
81 82
    }

83 84 85 86 87
  private:
    std::vector<bool> incrementAllowed_;
    std::vector<EntityTest> contains_;
    mutable MultiEntity<HostGrid> multiEntity_;
  };
88

89

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  template <int codim, PartitionIteratorType pitype, class HostGrid>
  class MultiMeshLeafIterator : public DummyIterator
  {
    using DummyIterator::DummyIterator;
  };

  template <PartitionIteratorType pitype, class HostGrid>
  class MultiMeshLeafIterator<0,pitype,HostGrid>
      : public MultiMeshIteratorBase<pitype,HostGrid,MultiMeshLeafIterator<0,pitype,HostGrid>>
  {
    using Self = MultiMeshLeafIterator;
    using Super = MultiMeshIteratorBase<pitype,HostGrid,Self>;
    using HostEntity = typename HostGrid::template Codim<0>::Entity;

  public:
    // Leaf iterator
    template <class GridImp>
    MultiMeshLeafIterator (tag::begin_iterator, const GridImp* multiMesh)
      : Super{tag::begin_iterator{}, multiMesh}
      , incrementAllowed_(multiMesh->size(), true)
      , multiEntity_(multiMesh->size())
    {
      this->initialIncrement();
113 114
    }

115 116 117 118 119 120 121
    // End iterator
    template <class GridImp>
    MultiMeshLeafIterator (tag::end_iterator, const GridImp* multiMesh)
      : Super{tag::end_iterator{}, multiMesh}
    {}

    void initialIncrement_impl ()
122
    {
123 124
      for (std::size_t i = 0; i < this->size(); ++i)
        this->initialIncrement(i);
125
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
126

127
    void increment_impl ()
Praetorius, Simon's avatar
Praetorius, Simon committed
128
    {
129 130
      for (std::size_t i = 0; i < this->size(); ++i)
        incrementAllowed_[i] = this->incrementAllowed(i);
Praetorius, Simon's avatar
Praetorius, Simon committed
131

132
      for (std::size_t i = 0; i < this->size(); ++i) {
Praetorius, Simon's avatar
Praetorius, Simon committed
133
        if (incrementAllowed_[i])
134
          this->increment(i);
Praetorius, Simon's avatar
Praetorius, Simon committed
135 136 137
      }
    }

138
    const MultiEntity<HostGrid>& dereference_impl () const
Praetorius, Simon's avatar
Praetorius, Simon committed
139
    {
140
      // update entries in multiEntity that have changed
141
      for (std::size_t i = 0; i <  this->size(); ++i) {
142
        if (incrementAllowed_[i])
143
          multiEntity_[i] = this->dereference(i);
144 145
      }
      return multiEntity_;
Praetorius, Simon's avatar
Praetorius, Simon committed
146 147
    }

148
    bool levelReached_impl (std::size_t /*i*/, const HostEntity& entity) const
Praetorius, Simon's avatar
Praetorius, Simon committed
149
    {
150
      return entity.isLeaf();
Praetorius, Simon's avatar
Praetorius, Simon committed
151 152
    }

153 154 155 156
  private:
    std::vector<bool> incrementAllowed_;
    mutable MultiEntity<HostGrid> multiEntity_;
  };
Praetorius, Simon's avatar
Praetorius, Simon committed
157 158


159 160 161 162 163 164 165 166 167 168 169 170 171
  template <int codim, PartitionIteratorType pitype, class HostGrid>
  class MultiMeshMasterLeafIterator : public DummyIterator
  {
    using DummyIterator::DummyIterator;
  };

  template <PartitionIteratorType pitype, class HostGrid>
  class MultiMeshMasterLeafIterator<0,pitype,HostGrid>
      : public MultiMeshIteratorBase<pitype,HostGrid,MultiMeshMasterLeafIterator<0,pitype,HostGrid>>
  {
    using Self = MultiMeshMasterLeafIterator;
    using Super = MultiMeshIteratorBase<pitype,HostGrid,Self>;
    using HostEntity = typename HostGrid::template Codim<0>::Entity;
172

173 174 175 176 177 178 179 180 181 182 183
  public:
    // Leaf iterator
    template <class GridImp>
    MultiMeshMasterLeafIterator (tag::begin_iterator, const GridImp* multiMesh, std::size_t master)
      : Super{tag::begin_iterator{}, multiMesh}
      , incrementAllowed_(multiMesh->size(), true)
      , level_(multiMesh->size())
      , multiEntity_(multiMesh->size())
      , master_(master)
    {
      this->initialIncrement();
Praetorius, Simon's avatar
Praetorius, Simon committed
184 185
    }

186 187 188 189 190 191 192 193
    // End iterator
    template <class GridImp>
    MultiMeshMasterLeafIterator (tag::end_iterator, const GridImp* multiMesh)
      : Super{tag::end_iterator{}, multiMesh}
    {}

    // first increment the master grid then the others
    void initialIncrement_impl ()
Praetorius, Simon's avatar
Praetorius, Simon committed
194
    {
195 196 197 198
      level_[master_] = this->initialIncrement(master_);
      for (std::size_t i = 0; i < this->size(); ++i)
        if (i != master_)
          level_[i] = this->initialIncrement(i);
Praetorius, Simon's avatar
Praetorius, Simon committed
199 200
    }

201 202
    // first increment the master grid then the others
    void increment_impl ()
Praetorius, Simon's avatar
Praetorius, Simon committed
203
    {
204 205 206 207 208 209 210 211
      for (std::size_t i = 0; i < this->size(); ++i)
        incrementAllowed_[i] = this->incrementAllowed(i);

      if (incrementAllowed_[master_])
        level_[master_] = this->increment(master_);
      for (std::size_t i = 0; i < this->size(); ++i) {
        if (i != master_ && incrementAllowed_[i])
          level_[i] = this->increment(i);
212
      }
Praetorius, Simon's avatar
Praetorius, Simon committed
213 214
    }

215
    const MultiEntity<HostGrid>& dereference_impl () const
Praetorius, Simon's avatar
Praetorius, Simon committed
216
    {
217 218 219 220
      // update entries in multiEntity that have changed
      for (std::size_t i = 0; i <  this->size(); ++i) {
        if (incrementAllowed_[i])
          multiEntity_[i] = this->dereference(i);
221
      }
222 223 224 225 226 227 228
      return multiEntity_;
    }

    // got down to leaf entity on master grid and until the master grid level for the other grids
    bool levelReached_impl (std::size_t i, const HostEntity& entity) const
    {
      return (i == master_ && entity.isLeaf()) || entity.level() == level_[master_];
Praetorius, Simon's avatar
Praetorius, Simon committed
229 230 231
    }

  private:
232
    std::vector<bool> incrementAllowed_;
233
    std::vector<int> level_;
234
    mutable MultiEntity<HostGrid> multiEntity_;
235
    std::size_t master_;
Praetorius, Simon's avatar
Praetorius, Simon committed
236 237
  };

238 239 240

  template <PartitionIteratorType pitype = All_Partition, class Grid>
  inline auto master_leaf_elements(Grid const& multiMesh, std::size_t master)
241
  {
242
    using Iterator = MultiMeshMasterLeafIterator<0,pitype,typename Grid::HostGrid>;
243
    using Range = IteratorRange<Iterator>;
244 245
    return Range{ Iterator{tag::begin_iterator{}, &multiMesh, master},
                  Iterator{tag::end_iterator{}, &multiMesh} };
246 247
  }

Praetorius, Simon's avatar
Praetorius, Simon committed
248 249 250
}  // end namespace Dune

#endif // DUNE_MULTIMESH_ITERATOR_HH