Mesh.hpp 4.65 KB
Newer Older
1
2
3
4
#pragma once

#include <array>
#include <memory>
5
#include <string>
6

7
#include <dune/common/filledarray.hh>
8
9
10
11
12
13
#include <dune/common/fvector.hh>

#include <dune/grid/albertagrid.hh>
#include <dune/grid/uggrid.hh>
#include <dune/grid/yaspgrid.hh>

14
15
16
#include <dune/grid/albertagrid/albertareader.hh>
#include <dune/grid/io/file/gmshreader.hh>

17
18
19
#include <amdis/Initfile.hpp>
#include <amdis/Output.hpp>
#include <amdis/utility/Filesystem.hpp>
20
21
22

namespace AMDiS
{
23
  namespace tag
24
  {
25
26
27
28
    struct albertagrid {};
    struct uggrid {};
    struct yaspgrid {};
    struct unknowngrid {};
29

30
  } // end namespace tag
31

32
  namespace Impl
33
  {
34
35
36
37
38
    template <class Grid>
    struct MeshTag
    {
      using type = tag::unknowngrid;
    };
39

40
41
42
43
44
45
46
    // specialization for some grid types from DUNE
#if HAVE_ALBERTA
    template <int dim, int dimworld>
    struct MeshTag<Dune::AlbertaGrid<dim, dimworld>>
    {
      using type = tag::albertagrid;
    };
47
#endif
48

49
#if HAVE_UG
50
51
52
53
54
    template <int dim>
    struct MeshTag<Dune::UGGrid<dim>>
    {
      using type = tag::uggrid;
    };
55
#endif
56

57
58
59
60
61
    template <int dim, class Coordinates>
    struct MeshTag<Dune::YaspGrid<dim, Coordinates>>
    {
      using type = tag::yaspgrid;
    };
62

63
  } // end namespace Impl
64

65
66
  template <class Grid>
  using MeshTag_t = typename Impl::MeshTag<Grid>::type;
67
68


69
  /// A creator class for meshes. Each mesh needs different way of initialization
70
71
72
  template <class Grid>
  class MeshCreator
  {
73
    static std::unique_ptr<Grid> create(std::string meshName)
74
    {
75
      error_exit("Creator not yet implemented for this mesh type.");
76
77
    }
  };
78

79
80
81
82
83
#if HAVE_ALBERTA
  template <int dim, int dimworld>
  struct MeshCreator<Dune::AlbertaGrid<dim, dimworld>>
  {
    using Grid = Dune::AlbertaGrid<dim, dimworld>;
84

85
    static std::unique_ptr<Grid> create(std::string meshName)
86
87
88
89
90
91
    {
      std::string macro_filename = "";
      Parameters::get(meshName + "->macro file name", macro_filename);

      // TODO: if filename_extension is ".2d" or ".3d" read it directly from file
      // otherwise use a factory method
92

93
      return std::make_unique<Grid>(macro_filename);
94
95
96
    }
  };
#endif
97
98


99
100
101
102
103
#if HAVE_UG
  template <int dim>
  struct MeshCreator<Dune::UGGrid<dim>>
  {
    using Grid = Dune::UGGrid<dim>;
104

105
    static std::unique_ptr<Grid> create(std::string meshName)
106
    {
107

108
109
      std::string filename = "";
      Parameters::get(meshName + "->macro file name", filename);
110

111
      if (!filename.empty()) {
112
        filesystem::path fn(filename);
113
114
115
116
117
        auto ext = fn.extension();

#if HAVE_ALBERTA
        if (ext == "1d" || ext == "2d" || ext == "3d") {
          Dune::GridFactory<Grid> factory;
118
          Dune::AlbertaReader<Grid> reader;
119
          reader.readGrid(filename, factory);
120
          return std::unique_ptr<Grid>{factory.createGrid()};
121
122
123
124
        }
#endif
        if (ext == "msh") {
          Dune::GmshReader<Grid> reader;
125
          return std::unique_ptr<Grid>{reader.read(filename)};
126
127
        }
      } else {
128
        error_exit("Construction of UGGrid without filename not yet implemented!");
129
      }
130
131

      error_exit("No way to construct UG-Grid found");
132
      return {};
133
134
135
    }
  };
#endif
136

137
138
139
140
  template <int dim, class T>
  struct MeshCreator<Dune::YaspGrid<dim, Dune::EquidistantCoordinates<T,dim>>>
  {
    using Grid = Dune::YaspGrid<dim, Dune::EquidistantCoordinates<T,dim>>;
141

142
    static std::unique_ptr<Grid> create(std::string meshName)
143
144
145
    {
      Dune::FieldVector<double, dim> L; L = 1.0;  // extension of the domain
      Parameters::get(meshName + "->dimension", L);
146
147
148

      msg("L = ", L);

149
      auto s = Dune::filledArray<std::size_t(dim)>(1); // number of cells on coarse mesh in each direction
150
      Parameters::get(meshName + "->num cells", s);
151

152
      // TODO: add more parameters for yasp-grid (see constructor)
153

154
      return std::make_unique<Grid>(L, s);
155
156
    }
  };
157
158


159
160
161
162
  template <int dim, class T>
  struct MeshCreator<Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<T, dim>>>
  {
    using Grid = Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<T, dim>>;
163

164
    static std::unique_ptr<Grid> create(std::string meshName)
165
    {
166
167
      Dune::FieldVector<double, dim> lowerleft;  lowerleft = 0.0; // Lower left corner of the domain
      Dune::FieldVector<double, dim> upperright; upperright = 1.0; // Upper right corner of the domain
168
169
      Parameters::get(meshName + "->min corner", lowerleft);
      Parameters::get(meshName + "->max corner", upperright);
170

171
      auto s = Dune::filledArray<std::size_t(dim)>(1); // number of cells on coarse mesh in each direction
172
      Parameters::get(meshName + "->num cells", s);
173

174
      // TODO: add more parameters for yasp-grid (see constructor)
175

176
      return std::make_unique<Grid>(lowerleft, upperright, s);
177
178
179
180
    }
  };

} // end namespace AMDiS