7#ifndef KERNEL_GEOMETRY_ADAPTIVE_EXPORT_VTU_HPP
8#define KERNEL_GEOMETRY_ADAPTIVE_EXPORT_VTU_HPP 1
10#include <kernel/geometry/adaptive_mesh.hpp>
11#include <kernel/geometry/adaptive_mesh_layer.hpp>
12#include <kernel/geometry/export_vtk.hpp>
18 template<
typename MeshType_>
21 template<
typename TemplateSet_,
typename Shape_>
25 typedef Shape_ ShapeType;
31 static constexpr int shape_dim = ShapeType::dimension;
40 Index _num_verts_reg, _num_verts_ada, _num_verts_total;
42 Index _num_elems_reg, _num_elems_ada, _num_elems_total;
45 std::vector<char> _reg_elem_mask;
47 std::deque<std::pair<String, std::vector<double>>> _vertex_scalars;
48 std::deque<std::pair<String, std::vector<double>>> _cell_scalars;
52 _mesh_reg(mesh.foundation_mesh()),
54 _num_verts_reg(_mesh_reg.get_num_entities(0)),
55 _num_verts_ada(mesh.get_num_entities(0)),
56 _num_verts_total(_num_verts_reg + _num_verts_ada),
57 _num_elems_reg(_mesh_reg.get_num_entities(shape_dim)),
58 _num_elems_ada(mesh.get_num_entities(shape_dim)),
60 _num_elems_reg + _num_elems_ada - mesh.adaptive_mesh().get_num_entities(Geometry::
Layer{0}, shape_dim)),
61 _reg_elem_mask(_num_elems_reg, 1)
64 Index count = _num_elems_ada;
65 for(
Index i(0); i < _num_elems_reg; ++i)
66 count +=
Index(_reg_elem_mask[i] = (mesh.
adaptive_mesh().get_overlap_cell(i).has_value() ? 0 : 1));
67 XASSERTM(_num_elems_total == count,
"invalid element count");
75 AdaptiveExportVTU(
const AdaptiveExportVTU&) =
delete;
76 AdaptiveExportVTU& operator=(
const AdaptiveExportVTU&) =
delete;
78 template<
typename Br
idgeVector_>
79 void add_vertex_scalar(
const String& name,
const BridgeVector_& bridge_vector)
81 XASSERTM(bridge_vector.regular().size() == _num_verts_reg,
"invalid number of regular values in bridge vector");
83 bridge_vector.adaptive().size() == _num_verts_ada,
84 "invalid number of adaptive values in bridge vector");
86 const auto* val_reg = bridge_vector.regular().elements();
87 const auto* val_ada = bridge_vector.adaptive().elements();
89 std::vector<double> values(_num_verts_total);
91 for(
Index i(0); i < _num_verts_reg; ++i)
92 values[i] =
double(val_reg[i]);
93 for(
Index i(0); i < _num_verts_ada; ++i)
94 values[_num_verts_reg + i] =
double(val_ada[i]);
96 _vertex_scalars.push_back(std::make_pair(name, std::move(values)));
99 template<
typename Br
idgeVector_>
100 void add_cell_scalar(
const String& name,
const BridgeVector_& bridge_vector)
102 XASSERTM(bridge_vector.regular().size() == _num_elems_reg,
"invalid number of regular values in bridge vector");
104 bridge_vector.adaptive().size() == _num_elems_ada,
105 "invalid number of adaptive values in bridge vector");
107 const auto* val_reg = bridge_vector.regular().elements();
108 const auto* val_ada = bridge_vector.adaptive().elements();
110 std::vector<double> values(_num_elems_total);
113 for(
Index i(0); i < _num_elems_reg; ++i)
115 if(_reg_elem_mask[i] > 0)
117 values[j] = double(val_reg[i]);
121 for(
Index i(0); i < _num_elems_ada; ++i, ++j)
122 values[j] =
double(val_ada[i]);
123 XASSERT(j == _num_elems_total);
125 _cell_scalars.push_back(std::make_pair(name, std::move(values)));
128 void write(
const String& filename)
const
130 String vtu_name(filename +
".vtu");
131 std::ofstream ofs(vtu_name.c_str());
132 if(!(ofs.is_open() && ofs.good()))
133 throw FileError(
"Failed to create '" + vtu_name +
"'");
142 void write_vtu(std::ostream& os)
const
145 const int verts_per_cell = Shape::FaceTraits<ShapeType, 0>::count;
148 os <<
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\">\n";
151 os <<
"<UnstructuredGrid>\n";
152 os <<
"<Piece NumberOfPoints=\"" << _num_verts_total <<
"\" NumberOfCells=\"" << _num_elems_total <<
"\">\n";
155 if((!_vertex_scalars.empty()) )
157 os <<
"<PointData>\n";
160 for(
Index i(0); i <
Index(_vertex_scalars.size()); ++i)
162 const auto& var(_vertex_scalars[i]);
163 os <<
"<DataArray type=\"Float64\" Name=\"" << var.first <<
"\" Format=\"ascii\">\n";
164 for(
Index j(0); j < _num_verts_total; ++j)
168 os <<
"</DataArray>\n";
185 os <<
"</PointData>\n";
189 if(!_cell_scalars.empty() )
191 os <<
"<CellData>\n";
192 if(!_cell_scalars.empty())
194 for(
Index i(0); i <
Index(_cell_scalars.size()); ++i)
196 const auto& var(_cell_scalars[i]);
197 os <<
"<DataArray type=\"Float64\" Name=\"" << var.first <<
"\" Format=\"ascii\">\n";
198 for(
Index j(0); j < _num_elems_total; ++j)
202 os <<
"</DataArray>\n";
223 os <<
"</CellData>\n";
231 os <<
"<DataArray type=\"Float32\" NumberOfComponents=\"3\" Format=\"ascii\">\n";
233 for(
Index i(0); i < _num_verts_reg; ++i)
236 for(
int j(1); j < shape_dim; ++j)
238 os <<
" " << vtx_reg[i][j];
240 for(
int j(shape_dim); j < 3; ++j)
247 for(
Index i(0); i < _num_verts_ada; ++i)
250 for(
int j(1); j < shape_dim; ++j)
252 os <<
" " << vtx_ada[i][j];
254 for(
int j(shape_dim); j < 3; ++j)
260 os <<
"</DataArray>\n";
264 const auto& idx_reg = _mesh_reg.template get_index_set<shape_dim, 0>();
265 const auto& idx_ada = _mesh_ada.template get_index_set<shape_dim, 0>();
267 os <<
"<DataArray type=\"UInt32\" Name=\"connectivity\">\n";
269 for(
Index i(0); i < _num_elems_reg; ++i)
272 if(_reg_elem_mask[i] > 0)
274 os << idx_reg(i, VTKShapeType::map(0));
275 for(
int j(1); j < verts_per_cell; ++j)
277 os <<
" " << idx_reg(i, VTKShapeType::map(j));
283 for(
Index i(0); i < _num_elems_ada; ++i)
285 os << (_num_verts_reg + idx_ada(i, VTKShapeType::map(0)));
286 for(
int j(1); j < verts_per_cell; ++j)
288 os <<
" " << (_num_verts_reg + idx_ada(i, VTKShapeType::map(j)));
292 os <<
"</DataArray>\n";
293 os <<
"<DataArray type=\"UInt32\" Name=\"offsets\">\n";
294 for(
Index i(0); i < _num_elems_total; ++i)
296 os << ((i + 1) * verts_per_cell) <<
"\n";
298 os <<
"</DataArray>\n";
299 os <<
"<DataArray type=\"UInt32\" Name=\"types\">\n";
300 for(
Index i(0); i < _num_elems_total; ++i)
302 os << VTKShapeType::type <<
"\n";
304 os <<
"</DataArray>\n";
309 os <<
"</UnstructuredGrid>\n";
310 os <<
"</VTKFile>\n";
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
const Geometry::AdaptiveMeshLayer< MeshType > & _mesh_ada
the chosen adaptive mesh layer
const MeshType::FoundationMeshType & _mesh_reg
the underlying regular mesh
Intern::VTKShape< ShapeType > VTKShapeType
our VTK shape type
Dynamic mesh data structure.
ConformalMesh interface for adaptive meshes.
AdaptiveMeshType & adaptive_mesh()
accessor for adaptive mesh
VertexSetType & get_vertex_set()
Returns the vertex set of this mesh.
String class implementation.
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
std::uint64_t Index
Index data type.
Newtype wrapper for mesh layers.