VTKP1Writer.cpp 7.66 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * Copyright (c) 2017-2021 Dominik Thoennes, Marcus Mohr, Nils Kohl.
 *
 * This file is part of HyTeG
 * (see https://i10git.cs.fau.de/hyteg/hyteg).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include "hyteg/dataexport/VTKP1Writer.hpp"

#include "core/DataTypes.h"

#include "hyteg/dataexport/VTKHelpers.hpp"
#include "hyteg/dataexport/VTKOutput.hpp"

27
28
29
// from walberla
#include "vtk/UtilityFunctions.h"

30
31
namespace hyteg {

32
33
using walberla::vtk::typeToString;

34
35
void VTKP1Writer::write( const VTKOutput& mgr, std::ostream& output, const uint_t& level )
{
36
   if ( mgr.getNumRegisteredFunctions( vtk::DoFType::VERTEX ) == 0 )
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
   {
      return;
   }

   auto storage = mgr.storage_;

   const uint_t numberOfPoints2D = storage->getNumberOfLocalFaces() * levelinfo::num_microvertices_per_face( level );
   const uint_t numberOfCells2D  = storage->getNumberOfLocalFaces() * levelinfo::num_microfaces_per_face( level );

   const uint_t numberOfPoints3D = storage->getNumberOfLocalCells() * levelinfo::num_microvertices_per_cell( level );
   const uint_t numberOfCells3D  = storage->getNumberOfLocalCells() * levelinfo::num_microcells_per_cell( level );

   if ( mgr.write2D_ )
   {
      vtk::writePieceHeader( output, numberOfPoints2D, numberOfCells2D );
   }
   else
   {
      vtk::writePieceHeader( output, numberOfPoints3D, numberOfCells3D );
   }

   output << "<Points>\n";
59
   vtk::openDataElement( output, typeToString< real_t >(), "", 3, mgr.vtkDataFormat_ );
60

61
   VTKMeshWriter::writePointsForMicroVertices( mgr, output, storage, level );
62
63
64
65
66
67

   output << "\n</DataArray>\n";
   output << "</Points>\n";

   if ( mgr.write2D_ )
   {
68
      VTKMeshWriter::writeCells2D( mgr, output, storage, levelinfo::num_microvertices_per_edge( level ) );
69
70
71
   }
   else
   {
72
      VTKMeshWriter::writeCells3D( mgr, output, storage, levelinfo::num_microvertices_per_edge( level ) );
73
74
75
76
   }

   output << "<PointData>\n";

77
   // write all scalar P1Functions of supported value type
78
   for ( const auto& function : mgr.p1Functions_.getFunctions< double >() )
79
80
81
   {
      writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
   }
82
   for ( const auto& function : mgr.p1Functions_.getFunctions< int32_t >() )
83
84
85
   {
      writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
   }
86
   for ( const auto& function : mgr.p1Functions_.getFunctions< int64_t >() )
87
88
89
90
   {
      writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
   }

91
92
93
94
95
96
97
98
99
   for ( const auto& function : mgr.p1VecFunctions_.getFunctions< double >() )
   {
      writeVectorFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
   }
   for ( const auto& function : mgr.p1VecFunctions_.getFunctions< int32_t >() )
   {
      writeVectorFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
   }
   for ( const auto& function : mgr.p1VecFunctions_.getFunctions< int64_t >() )
100
101
102
103
104
105
106
107
108
   {
      writeVectorFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
   }

   output << "</PointData>\n";

   vtk::writePieceFooter( output );
}

109
110
111
112
113
114
115
template < typename value_t >
void VTKP1Writer::writeScalarFunction( std::ostream&                                  output,
                                       const vertexdof::VertexDoFFunction< value_t >& function,
                                       const std::shared_ptr< PrimitiveStorage >&     storage,
                                       const uint_t&                                  level,
                                       bool                                           write2D,
                                       vtk::DataFormat                                vtkDataFormat )
116
{
117
   WALBERLA_ASSERT_EQUAL( storage, function.getStorage() );
118

119
   VTKOutput::VTKStreamWriter< value_t > streamWriter( vtkDataFormat );
120
   vtk::openDataElement( output, typeToString< value_t >(), function.getFunctionName(), 1, vtkDataFormat );
Marcus Mohr's avatar
Marcus Mohr committed
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
   if ( write2D )
   {
      for ( const auto& it : storage->getFaces() )
      {
         const Face& face = *it.second;

         size_t len = levelinfo::num_microvertices_per_face( level );

         for ( size_t i = 0; i < len; ++i )
         {
            streamWriter << face.getData( function.getFaceDataID() )->getPointer( level )[i];
         }
      }
   }
   else
   {
      for ( const auto& it : storage->getCells() )
      {
         const Cell& cell     = *it.second;
         const auto  cellData = cell.getData( function.getCellDataID() )->getPointer( level );

         for ( const auto& idxIt : vertexdof::macrocell::Iterator( level ) )
         {
            streamWriter << cellData[vertexdof::macrocell::index( level, idxIt.x(), idxIt.y(), idxIt.z() )];
         }
      }
   }

   streamWriter.toStream( output );
Marcus Mohr's avatar
Marcus Mohr committed
151
152

   output << "\n</DataArray>\n";
153
154
}

155
template < typename value_t >
156
void VTKP1Writer::writeVectorFunction( std::ostream&                              output,
157
                                       const P1VectorFunction< value_t >&         function,
158
159
160
161
162
                                       const std::shared_ptr< PrimitiveStorage >& storage,
                                       const uint_t&                              level,
                                       bool                                       write2D,
                                       vtk::DataFormat                            vtkDataFormat )
{
163
164
   WALBERLA_ASSERT_EQUAL( storage, function.getStorage() );

165
   VTKOutput::VTKStreamWriter< value_t > streamWriter( vtkDataFormat );
166

Marcus Mohr's avatar
Marcus Mohr committed
167
   uint_t dim = write2D ? 2 : 3;
168
   vtk::openDataElement( output, typeToString< value_t >(), function.getFunctionName(), dim, vtkDataFormat );
Marcus Mohr's avatar
Marcus Mohr committed
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
   if ( write2D )
   {
      for ( const auto& it : storage->getFaces() )
      {
         const Face& face = *it.second;

         size_t len = levelinfo::num_microvertices_per_face( level );

         for ( size_t i = 0; i < len; ++i )
         {
            streamWriter << face.getData( function[0].getFaceDataID() )->getPointer( level )[i];
            streamWriter << face.getData( function[1].getFaceDataID() )->getPointer( level )[i];
            // streamWriter << real_t(0); Paraview needs 3D vector fields to form glyphs
         }
      }
   }
   else
   {
      for ( const auto& it : storage->getCells() )
      {
         const Cell& cell      = *it.second;
         const auto  cellData0 = cell.getData( function[0].getCellDataID() )->getPointer( level );
         const auto  cellData1 = cell.getData( function[1].getCellDataID() )->getPointer( level );
         const auto  cellData2 = cell.getData( function[2].getCellDataID() )->getPointer( level );

         for ( const auto& idxIt : vertexdof::macrocell::Iterator( level ) )
         {
            streamWriter << cellData0[vertexdof::macrocell::index( level, idxIt.x(), idxIt.y(), idxIt.z() )];
            streamWriter << cellData1[vertexdof::macrocell::index( level, idxIt.x(), idxIt.y(), idxIt.z() )];
            streamWriter << cellData2[vertexdof::macrocell::index( level, idxIt.x(), idxIt.y(), idxIt.z() )];
         }
      }
   }

   streamWriter.toStream( output );
Marcus Mohr's avatar
Marcus Mohr committed
205
206

   output << "\n</DataArray>\n";
207
208
209
}

} // namespace hyteg