FileWriter.hpp 4.08 KB
Newer Older
1
2
3
4
5
6
7
#pragma once

#include <string>
#include <vector>
#include <array>
#include <memory>

8
#include <dune/grid/io/file/vtk/vtkwriter.hh>
9
#include <dune/grid/io/file/vtk/vtksequencewriter.hh>
10
#include <dune/geometry/referenceelements.hh>
11

12
13
#include <dune/amdis/Initfile.hpp>
#include <dune/amdis/common/Loops.hpp>
14
15
16
17

namespace AMDiS
{

18
19
20
21
  template <class Traits>
  class FileWriter
  {
  private: // typedefs and static constants
22

23
24
    using Mesh     = typename Traits::Mesh;
    using MeshView = typename Mesh::LeafGridView;
25

26
27
    /// Dimension of the mesh
    static constexpr int dim = Traits::dim;
28

29
30
    /// Dimension of the world
    static constexpr int dow = Traits::dimworld;
31

32
33
    /// Number of problem components
    static constexpr int nComponents = Traits::nComponents;
34
35


36
  public:
37

38
    /// Constructor.
39
    FileWriter(std::string base, MeshView const& meshView, std::vector<std::string> const& names_)
40
41
      : meshView(meshView)
      , names(names_)
42
    {
43
44
45
46
      filename = "solution";
      Parameters::get(base + "->filename", filename);
      dir = "output";
      Parameters::get(base + "->output directory", dir);
47

48
49
      vtkWriter = make_shared<Dune::VTKWriter<MeshView>>(meshView);
      vtkSeqWriter = make_shared<Dune::VTKSequenceWriter<MeshView>>(vtkWriter, filename, dir, "");
50
51
    }

52

53
    /// default write method for time-depended data
54
    template <class SystemVectorType>
55
    void write(double time, SystemVectorType const& solutions)
56
    {
57
58
      vtkWriter->clear();
      // copy dofvector to vertex data
59
      for_<0, nComponents>([this, &solutions](const auto _i)
60
61
62
63
64
65
      {
        this->dofVector2vertexVector(solutions[_i], std::get<_i>(data_vectors));
        vtkSeqWriter->addVertexData(std::get<_i>(data_vectors), names[_i]);
      });
      vtkSeqWriter->write(time/*, Dune::VTK::appendedraw*/);
    }
66

67
68
69

    /// default write method for stationary data
    template <class SystemVectorType>
70
    void write(SystemVectorType const& solutions)
71
72
73
    {
      vtkWriter->clear();
      // copy dofvector to vertex data
74
      for_<0, nComponents>([this, &solutions](const auto _i)
75
76
77
78
79
      {
        this->dofVector2vertexVector(solutions[_i], std::get<_i>(data_vectors));
        vtkWriter->addVertexData(std::get<_i>(data_vectors), names[_i]);
      });
      vtkWriter->pwrite(filename, dir, "" /*, Dune::VTK::appendedraw*/);
80
    }
81
82


83
  protected:
84

85
    template <class DOFVector, class Vector>
86
    void dofVector2vertexVector(DOFVector const& dofvector, Vector& data)
87
    {
88
89
      using Geometry = typename MeshView::template Codim<0>::Geometry;
      using RefElements = Dune::ReferenceElements<typename Geometry::ctype, Geometry::mydimension>;
90

91
      data.resize(meshView.size(dim));
92

93
94
      auto const& indexSet = meshView.indexSet();
      auto const& feSpace = dofvector.getFeSpace();
95

96
97
      auto localView = feSpace.localView();
      auto localIndexSet = feSpace.localIndexSet();
98

99
100
101
102
103
      // copy data to P1-vector
      for (auto const& element : elements(meshView)) {
        localView.bind(element);
        localIndexSet.bind(localView);
        auto const& localBasis = localView.tree().finiteElement().localBasis();
104

105
        auto const& refElement = RefElements::general(element.type());
106

107
        std::vector<Dune::FieldVector<double,1> > shapeValues;
108

109
110
111
112
        size_t nVertices = element.subEntities(dim);
        for (size_t i = 0; i < nVertices; ++i) {
          auto const& v = element.template subEntity<dim>(i);
          auto pos = refElement.position(i, dim);
113

114
          localBasis.evaluateFunction(pos, shapeValues);
115

116
117
118
119
120
121
122
123
          size_t idx = indexSet.index(v);
          data[idx] = 0.0;
          for (size_t j = 0; j < shapeValues.size(); ++j) {
            const auto global_idx = localIndexSet.index(j);
            data[idx] += dofvector[global_idx] * shapeValues[j];
          }
        }
      }
124
125
    }

126
  private:
127
    MeshView const& meshView;
128
129
    shared_ptr<Dune::VTKWriter<MeshView>> vtkWriter;
    shared_ptr<Dune::VTKSequenceWriter<MeshView>> vtkSeqWriter;
130

131
132
    std::vector<std::string> names;
    std::array<std::vector<double>, nComponents> data_vectors;
133

134
135
136
    std::string filename;
    std::string dir;
  };
137
138

} // end namespace AMDiS