GridTransferManager.hpp 3.27 KB
Newer Older
1
2
3
4
5
6
7
#pragma once

#include <cstdint>
#include <map>
#include <memory>

#include <amdis/GridTransfer.hpp>
8
#include <amdis/common/ConcurrentCache.hpp>
9
10
11

namespace AMDiS
{
12
13
14
15
16
  /**
   * \addtogroup Adaption
   * @{
   **/

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  /// Static administration class for automatic handling of DOFVectors during grid adaption
  class GridTransferManager
  {
    template <class T1, class T2>
    friend class DOFVectorBase;

    using Self = GridTransferManager;
    using Key = std::uintptr_t;
    using Data = std::unique_ptr<GridTransferInterface>;

  private:
    // Constructors. Since this is a static class you cannot call any constructor.
    GridTransferManager() = delete;

  public:
    /**
     * \brief Adapts the grid according to previously set marks and performs data transfer on
     *        all DOFVectors associated to the given grid.
     *
     * This function retrieves the grid's stored GridTransfer and calls its adaptation methods.
     * During this process the grid will change according to previously set grid element markings.
     * All DOFVectors associated to the given grid will be interpolated to the new grid according to
     * their DataTransfer member object.
     *
     * Takes a grid as argument. Marking of the grid needs to be performed prior to calling this.
     * Returns true if the grid changed during adaptation.
     **/
44
45
    template <class Grid, class ...Bases>
    static bool adapt(Grid& grid, Bases&... bases)
46
47
48
49
    {
      auto gridTransfer = GridTransferManager::gridTransfer(grid);
      bool adapted = gridTransfer.preAdapt();
      adapted |= gridTransfer.adapt();
50
51
      // call basis.update(basis.gridView()) on all bases
      (void)std::initializer_list<int>({0, (bases.update(bases.gridView()),0)...});
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
      gridTransfer.postAdapt();
      return adapted;
    }

    /// Returns the GridTransfer corresponding to a Grid, to be used during the adaptation cycle
    template <class Grid>
    static GridTransfer<Grid>& gridTransfer(Grid& grid)
    {
      GridTransfer<Grid>* gridTransfer
        = dynamic_cast<GridTransfer<Grid>*>(Self::gridTransferInterface(grid));
      gridTransfer->bind(grid);
      return *gridTransfer;
    }

  private:
    // DOFVector registration methods. They are called automaticly by the DOFVectors.
    template <class Vec>
    static void attach(Vec& vec)
    {
      auto const& grid = vec.basis().gridView().grid();
      Self::gridTransferInterface(grid)->attach(&vec);
    }

    template <class Vec>
    static void detach(Vec& vec)
    {
      auto const& grid = vec.basis().gridView().grid();
      Self::gridTransferInterface(grid)->detach(&vec);
    }

    // Returns the GridTransferInterface class,
    //   used for attaching and detaching DOFVectors to a GridTransfer
    template <class Grid>
    static GridTransferInterface* gridTransferInterface(Grid const &grid)
    {
      Key key = Key(&grid);
88
89
      GridTransferCache cache;
      auto& gridTransferInterfaceUniquePtr = cache.get(key, [&](Key const&)
90
91
92
93
94
95
96
97
98
99
100
      {
        return std::make_unique<GridTransfer<Grid>>();
      });
      return gridTransferInterfaceUniquePtr.get();
    }

  private:
    // Associate to each Grid (represented as address) a GridTransfer
    using GridTransferCache = ConcurrentCache< Key, Data, StaticLockedPolicy, std::map<Key, Data> >;
  };

101
102
  /// @}

103
} // end namespace AMDiS