Mesh.hpp 4.67 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
  template <class Grid>
71
  struct MeshCreator
72
  {
73
    static std::unique_ptr<Grid> create(std::string meshName)
74
    {
75
      error_exit("Creator not yet implemented for this mesh type.");
76
      return {};
77
78
    }
  };
79

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

86
    static std::unique_ptr<Grid> create(std::string meshName)
87
88
89
90
91
92
    {
      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
93

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


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

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

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

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

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

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

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

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

      msg("L = ", L);

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

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

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


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

165
    static std::unique_ptr<Grid> create(std::string meshName)
166
    {
167
168
      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
169
170
      Parameters::get(meshName + "->min corner", lowerleft);
      Parameters::get(meshName + "->max corner", upperright);
171

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

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

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

} // end namespace AMDiS