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.