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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#ifndef FPMAMESHWRITER_H
#define FPMAMESHWRITER_H
#include "MeshWriter.h"
#include "../../MeshElements/MeshElement.h"
#include "../../MeshDataContainer/MeshDataContainer.h"
#include "../../MeshFunctions/MeshFunctions.h"
#include <map>
#include <ostream>
template<unsigned int MeshDimension, typename IndexType = size_t, typename Real = double>
class FPMAMeshWriter : public MeshWriter<MeshDimension>{
public:
FPMAMeshWriter() = default;
template<unsigned int ...Reserve>
FPMAMeshWriter(const MeshElements<MeshDimension, IndexType, Real, Reserve...>&){}
};
template<typename IndexType, typename Real>
class FPMAMeshWriter<3, IndexType, Real> : public MeshWriter<3>{
using writer = MeshWriter<3>;
size_t lastHash;
/**
* @brief faceVert<HR>
* correctly erdered vertices for all faces
*/
MeshDataContainer<std::vector<IndexType>, 2> faceVert;
/**
* @brief cellFace<HR>
* original order of faces
*/
MeshDataContainer<std::vector<IndexType>, 3> cellFace;
/**
* @brief indexFace<HR>
* This funcion return indexes of vertices of a face in correct order
* with respect to edge orientation
* in output vector verticesIndexed
* @param mesh the structure of the mesh
* @param face the face of the mesh to be indexed
* @param cell the cell which are the vertices being indexed to
* @param faceEdgeOri the orientation of the edges to the faces
* @param verticesIndexed output vector of indexed vertices
*/
template<unsigned int ...Reserve>
void indexFace(MeshElements<3, IndexType, Real, Reserve...>& mesh,
typename MeshElements<3, IndexType, Real, Reserve...>::Face& face,
std::vector<IndexType>& verticesIndexed){
// export the face in "left" direction see VTK export
IndexType startVertex = mesh.getEdges().at(face.getSubelements()[0].index).getVertexBIndex();
IndexType nextVertex = mesh.getEdges().at(face.getSubelements()[0].index).getVertexAIndex();
verticesIndexed.push_back(startVertex);
IndexType lastWrittenEdge = face.getSubelements()[0].index;
while (startVertex != nextVertex){
for (auto& sube : face.getSubelements()) {
auto &edge = mesh.getEdges().at(sube.index);
if (edge.getIndex() != lastWrittenEdge) {
if (edge.getVertexAIndex() == nextVertex) {
lastWrittenEdge = edge.getIndex();
verticesIndexed.push_back(edge.getVertexAIndex());
nextVertex = edge.getVertexBIndex();
} else if (edge.getVertexBIndex() == nextVertex) {
lastWrittenEdge = edge.getIndex();
verticesIndexed.push_back(edge.getVertexBIndex());
nextVertex = edge.getVertexAIndex();
}
}
}
}
verticesIndexed.shrink_to_fit();
}
/**
* @brief indexMesh<HR>
* This function creates vector of indexes of vertices for each cell in order suitable
* for VTK output. Moreover in case of elements type different from
* any VTK cell type, the cell is split into tetrahedrons. The tetrahedrons are
* made for each edge of every faces. The tetrahedrons is made of both edges vertices
* and cell and face center.
* @param mesh Mesh to be indexed
* @param cellTypes Vector of known cell types. If a cell type is not known then a method
* of splitting into tetrahedrons is used.
*/
template<unsigned int ...Reserve>
void indexMesh(MeshElements<3, IndexType, Real, Reserve...>& mesh){
faceVert.template getDataByPos<0>().clear();
faceVert.alocateData(mesh);
DBGMSG("indexing mesh");
// write cells of the mesh
// prepare connections
auto cellVert = MeshConnections<3,0>::connections(mesh);
for (typename MeshElements<3, IndexType, Real, Reserve...>::Face& face : mesh.getFaces()){
indexFace(mesh, face, faceVert.at(face));
}
cellFace = MeshConnections<3,2, Order::ORDER_ORIGINAL>::connections(mesh);
}
public:
/**
* @brief writeToStream
* Exports the mesh to the output stream in VTK format.
* If the mesh is written for the first time, it is indexed.
* @see indexMesh
* @param ost
* @param mesh
* @param cellTypes the types of cells in NativeType format
*/
template<unsigned int ...Reserve>
void writeToStream(std::ostream& ost,
MeshElements<3, IndexType, Real, Reserve...>& mesh){
// create index of mesh if the mesh has changed
size_t curHash = writer::computeHash(mesh);
// if the mesh is not the same as it was,
// then update the index
if (lastHash != curHash){
indexMesh(mesh);
}
lastHash = curHash;
// first write verices
ost << mesh.getVertices().size() << std::endl;
for(auto& vert : mesh.getVertices()) {
ost << vert[0] << ' ' << vert[1] << ' ' << vert[2] <<"\n";
}
ost << std::endl;
// write faces
ost << mesh.getFaces().size() << std::endl;
for(auto& face : mesh.getFaces()) {
ost << faceVert.at(face).size() << ' ';
for (IndexType& vertIndex : faceVert.at(face)) {
ost << vertIndex << ' ';
}
ost << std::endl;
}
// write cells of the mesh
ost << mesh.getCells().size() << std::endl;
for(auto& cell : mesh.getCells()) {
ost << cellFace.at(cell).size() << ' ';
for (IndexType& faceIndex : cellFace.at(cell)) {
ost << faceIndex << ' ';
}
ost << std::endl;
}
ost << 0;
}
};
#endif // FPMAMESHWRITER_H