GridTransfer.hpp 3.5 KB
Newer Older
1
2
#pragma once

3
#include <list>
4

5
#include <amdis/Output.hpp>
6
#include <amdis/linearalgebra/DOFVectorInterface.hpp>
7

8
9
namespace AMDiS
{
10
11
12
13
14
15
  /**
   * \addtogroup Adaption
   * @{
   **/

  /// \brief Interface for transfer between grid changes to be registered in a \ref GridTransferManager
16
17
18
19
20
  class GridTransferInterface
  {
  public:
    virtual ~GridTransferInterface() = default;

21
    /// Attach a data container to the grid transfer, that gets interpolated during grid change
22
    virtual void attach(DOFVectorInterface*) = 0;
23
24

    /// Remove a data constainer from the grid transfer. Throws a warning if container not found.
25
    virtual void detach(DOFVectorInterface*) = 0;
26
27

    /// Prepare the grid and the data for the adaption
28
    virtual bool preAdapt() = 0;
29
30

    /// Do the grid adaption
31
    virtual bool adapt() = 0;
32
33

    // Perform data adaption to the new grid
34
35
36
37
    virtual void postAdapt() = 0;
  };


38
  /// \brief Implementation of \ref GridTransferInterface for concrete Grid type.
39
40
  template <class Grid>
  class GridTransfer
41
      : public GridTransferInterface
42
43
44
45
  {
    using Self = GridTransfer;

  public:
46
47
    /// Bind a (mutable) grid to this GridTransfer. Must be called before any xxxAdapt() method.
    // [[ensures: bound()]]
48
49
50
51
52
    void bind(Grid& grid)
    {
      grid_ = &grid;
    }

53
54
    /// Release the grid from this GridTransfer
    // [[ensures: not bound()]]
55
56
57
58
    void unbind()
    {
      grid_ = nullptr;
    }
59

60
61
62
63
64
65
66
    /// Returns whether this GridTransfer is bound to a grid.
    bool bound() const
    {
      return grid_ != nullptr;
    }

    /// Implements \ref GridTransferInterface::attach
67
    void attach(DOFVectorInterface* vec) override
68
69
70
71
    {
      data_.push_back(vec);
    }

72
    /// Implements \ref GridTransferInterface::detach
73
    void detach(DOFVectorInterface* vec) override
74
75
76
77
78
79
80
81
    {
      auto it = std::find(data_.begin(), data_.end(), vec);
      if (it != data_.end())
        data_.erase(it);
      else
        warning("DOFVector to detach not found");
    }

82
83
    /// Implements \ref GridTransferInterface::preAdapt
    // [[expects: bound()]]
84
    bool preAdapt() override
85
    {
86
87
      assert(bound());
      mightCoarsen_ = grid_->preAdapt();
88
      for (auto* vec : this->data_)
89
90
91
92
        vec->preAdapt(mightCoarsen_);
      return mightCoarsen_;
    }

93
94
    /// Implements \ref GridTransferInterface::adapt
    // [[expects: bound()]]
95
    bool adapt() override
96
    {
97
98
      assert(bound());
      refined_ = grid_->adapt();
99
100
101
      return refined_;
    }

102
103
    /// Implements \ref GridTransferInterface::postAdapt
    // [[expects: bound()]]
104
    void postAdapt() override
105
    {
106
      assert(bound());
107
      if (mightCoarsen_ || refined_) {
108
        for (auto* vec : this->data_)
109
110
111
          vec->postAdapt(refined_);
      }
      grid_->postAdapt();
112
113
114
115
116
117
118
      changeIndex_++;
    }

    /// Returns the grid change index, see \ref changeIndex.
    unsigned long changeIndex() const
    {
      return changeIndex_;
119
120
    }

121
  private:
122
    /// A grid this GridTransfer is bound to in \ref bind()
123
    Grid* grid_ = nullptr;
124
125

    /// A list of data containers handled during grid adaption
126
    std::list<DOFVectorInterface*> data_;
127
128

    /// Flag set during \ref preAdapt(), indicating whether any element might be coarsened in \ref adapt()
129
    bool mightCoarsen_ = false;
130
131

    /// Flag set during \ref adapt() indicating that at least one entity was refined
132
    bool refined_ = false;
133

134
    /// This index is incremented every time the grid is changed, e.g. by refinement or coarsening.
135
    unsigned long changeIndex_ = 0;
136
137
  };

138
139
  /// @}

140
} // end namespace AMDiS