G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsParaviewUtils.hpp
1
13#pragma once
14
15// #include <gsCore/gsForwardDeclarations.h>
16#include<gsCore/gsField.h>
17#include <gsMSplines/gsMappedBasis.h> // Only to make linker happy
18#include <gsCore/gsDofMapper.h> // Only to make linker happy
19#include <gsCore/gsLinearAlgebra.h> // Only to make linker happy
22#include <gsIO/gsIOUtils.h>
24#include <gsIO/gsBase64.h>
25
26
27#include<fstream>
28#include<iostream>
29
30#define VTK_BEZIER_QUADRILATERAL 77
31
32namespace gismo
33{
34 template <class T>
35 std::vector<std::string> toVTK(const gsFunctionSet<T>& funSet,
36 unsigned nPts,
37 unsigned precision,
38 std::string label,
39 const bool& export_base64)
40 {
41 std::vector<std::string> out;
42 gsMatrix<T> evalPoint, xyzPoints;
43
44 // Loop over all patches
45 for ( index_t i=0; i != funSet.nPieces(); ++i )
46 {
47 gsGridIterator<T,CUBE> grid(funSet.piece(i).support(), nPts);
48
49 // Evaluate the MultiPatch for every parametric point of the grid iterator
50 xyzPoints.resize( funSet.targetDim(), grid.numPoints() );
51 index_t col = 0;
52 for( grid.reset(); grid; ++grid )
53 {
54 evalPoint = *grid; // ..
55 xyzPoints.col(col) = funSet.piece(i).eval(evalPoint);
56 col++;
57 }
58
59 if (xyzPoints.rows() < 3)
60 // Pad matrix with zeros
61 xyzPoints.conservativeResizeLike(gsEigen::MatrixXd::Zero(3,xyzPoints.cols()));
62
63 if (""!=label)
64 out.push_back( toDataArray(xyzPoints, {{"Name",label}}, precision, export_base64) );
65 else
66 out.push_back( toDataArray(xyzPoints, {{"",""}}, precision, export_base64) );
67 }
68 return out;
69 }
70
71 template <class T>
72 std::vector<std::string> toVTK(const gsField<T>& field,
73 unsigned nPts,
74 unsigned precision,
75 std::string label,
76 const bool& export_base64)
77 {
78 std::vector<std::string> out;
79 gsMatrix<T> evalPoint, xyzPoints;
80
81 // Loop over all patches
82 for ( index_t i=0; i != field.nPieces(); ++i )
83 {
84 gsGridIterator<T,CUBE> grid(field.fields().piece(i).support(), nPts);
85
86 // Evaluate the MultiPatch for every parametric point of the grid iterator
87 xyzPoints.resize( field.dim(), grid.numPoints());
88 index_t col = 0;
89 for( grid.reset(); grid; ++grid )
90 {
91 evalPoint = *grid; // ..
92 xyzPoints.col(col) = field.value(evalPoint, i);
93 col++;
94 }
95
96 if (""!=label)
97 out.push_back(
98 toDataArray(xyzPoints, {{"Name", label}}, precision, export_base64));
99 else
100 out.push_back(
101 toDataArray(xyzPoints, {{"", ""}}, precision, export_base64));
102
103 }
104 return out;
105 }
106
107 template <class MatrixType>
108 std::string toDataArray(const MatrixType & matrix,
109 std::map<std::string, std::string> attributes,
110 unsigned precision,
111 const bool& export_base64)
112 {
113 std::stringstream stream;
114
115 typedef typename MatrixType::Scalar T;
116
117 // Determing 'type' attribute based on input
118 const std::string vtk_typename = []() {
119 if (std::is_same<T, float>::value) {
120 return std::string("Float32");
121 } else if (std::is_same<T, double>::value) {
122 return std::string("Float64");
123 } else if (std::is_same<T, short int>::value) {
124 return std::string("Int8");
125 } else if (std::is_same<T, unsigned short int>::value) {
126 return std::string("UInt8");
127 } else if (std::is_same<T, int>::value) {
128 return std::string("Int16");
129 } else if (std::is_same<T, unsigned int>::value) {
130 return std::string("UInt16");
131 } else if (std::is_same<T, long int>::value) {
132 return std::string("Int32");
133 } else if (std::is_same<T, unsigned long int>::value) {
134 return std::string("UInt32");
135 } else if (std::is_same<T, long long int>::value) {
136 return std::string("Int64");
137 } else if (std::is_same<T, unsigned long long int>::value) {
138 return std::string("UInt64");
139 }
140 }();
141
142
143 // Header
144 stream << "<DataArray type=\"" << vtk_typename
145 << "\" format=\"";
146 if (export_base64) stream << "binary\" ";
147 else stream << "ascii\" ";
148
149 // Write attributes
150 for (auto const& block : attributes)
151 {
152 if (block.first!="")
153 stream << block.first <<"=\""<< block.second <<"\" ";
154 }
155 if (matrix.rows()>1)
156 stream << "NumberOfComponents=\"" << matrix.rows() << "\" ";
157 stream << ">\n";
158
159
160 if (export_base64) {
161
162 // Write data to vector to ensure it is 3D :/
163 std::vector<T> copy_of_matrix;
164 copy_of_matrix.reserve(matrix.cols() * matrix.rows());
165 // Note : Matrix is transposed
166 for (index_t j = 0; j < matrix.cols(); ++j) {
167 for (index_t i = 0; i < matrix.rows(); ++i) {
168 copy_of_matrix.push_back(matrix(i, j));
169 }
170 }
171
172 // Prepend the number of bytes to be expected (using a single-item
173 // array of unsigned 64 integers)
174 stream << Base64::Encode(std::vector<uint64_t>(1,copy_of_matrix.size() *
175 sizeof(T)))
176 // Write the actual data
177 + Base64::Encode(copy_of_matrix);
178 } else {
179 stream.setf(std::ios::fixed); // write floating point values in
180 // fixed-point notation.
181 stream.precision(precision);
182 // Format as vtk xml string
183 // stream << "<DataArray type=\"Float32\" format=\"ascii\" ";
184 // stream << "NumberOfComponents=\"3\">\n";
185 // For every point
186 for (index_t j = 0; j < matrix.cols(); ++j) {
187 for (index_t i = 0; i != matrix.rows(); ++i)
188 stream << matrix(i, j) << " ";
189 }
190 }
191 stream << "\n</DataArray>\n";
192
193 return stream.str();
194 }
195
196
197 template<class T>
198 // std::string BezierVTK(const gsGeometry<T> & geom)
199 std::string BezierVTK(const gsMultiPatch<T> & mPatch)
200 {
201 std::stringstream stream;
202
203 stream << "<?xml version=\"1.0\"?>\n"
204 << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" header_type=\"UInt32\">\n"
205 << "<UnstructuredGrid>\n";
206
207
208 const gsMultiPatch<T> bezierExt = mPatch.extractBezier();
209 index_t totalPoints = bezierExt.coefsSize();
210
211 // Set up matrices with cell data
212 gsMatrix<index_t> degrees(bezierExt.nPatches(),3);
213
214 gsMatrix<index_t> connectivity(1,totalPoints);
215 connectivity.asVector().setLinSpaced(0,totalPoints-1);
216
217 gsMatrix<index_t> offsets(1,bezierExt.nPatches());
218 index_t offset=0;
219
220 gsMatrix<index_t> types(1, bezierExt.nPatches());
221 types.setOnes();
222 types*= VTK_BEZIER_QUADRILATERAL;
223
224 gsMatrix<T> coefs(bezierExt.coefsSize(), bezierExt.targetDim());
225 gsMatrix<T> weights(bezierExt.coefsSize(),1);
226 weights.setOnes();
227
228 // For every patch / bezier element
229 for (size_t p=0;p<bezierExt.nPatches();++p)
230 {
231 // Control point ID transformation matrix
232 // from G+Smo notation to Paraview notation
233 gsMatrix<> IdTransform = vtkIDTransform(bezierExt.patch(p).degree(0)+1, bezierExt.patch(p).degree(1)+1);
234
235 // Fill matrices with Cell data
236 degrees.row(p) << bezierExt.patch(p).degree(0), bezierExt.patch(p).degree(1), 0;
237 offsets(p) = offset + bezierExt.patch(p).coefsSize();
238
239 // Tranform control points to vtk ordering and concatenate in coefs
240 coefs.middleRows(offset,bezierExt.patch(p).coefsSize()) = IdTransform * bezierExt.patch(p).coefs();
241 if (bezierExt.basis(p).isRational())
242 weights.middleRows(offset,bezierExt.patch(p).coefsSize()) = IdTransform * bezierExt.basis(p).weights();
243 offset += bezierExt.patch(p).coefsSize();
244 }
245
246 if (coefs.cols() == 2)
247 // Pad matrix with zeros
248 coefs.conservativeResizeLike(gsEigen::MatrixXd::Zero(coefs.rows(),3));
249
250 // Format to xml
251 stream <<"<Piece NumberOfPoints=\""<< totalPoints<<"\" NumberOfCells=\""<< bezierExt.nPatches()<<"\">\n";
252
253 stream << "<PointData RationalWeights=\"RationalWeights\">\n";
254 stream << "" << toDataArray( weights.transpose() ,{{"Name","RationalWeights"}});
255 stream << "</PointData>\n";
256
257
258 stream << "<CellData HigherOrderDegrees=\"HigherOrderDegrees\">\n";
259 stream << "" << toDataArray(degrees.transpose(),{{"Name","HigherOrderDegrees"}});
260 stream << "</CellData>\n";
261
262 stream << "<Points>\n";
263 stream << ""<< toDataArray( coefs.transpose(), {{"Name","Points"}});
264 stream << "</Points>\n";
265
266 stream << "<Cells>\n";
267 stream << toDataArray(connectivity, {{"Name","connectivity"}});
268 stream << toDataArray(offsets, {{"Name","offsets"}});
269 stream << toDataArray(types, {{"Name","types"}});
270 stream << "</Cells>\n";
271 stream << "</Piece>\n";
272 stream << "</UnstructuredGrid>\n";
273 stream << "</VTKFile>\n";
274
275 return stream.str();
276 }
277
278} // namespace gismo
279#undef VTK_BEZIER_QUADRILATERAL
280
static std::string Encode(const std::vector< BaseType > &data_vector)
Helper routine for std::vector data.
Definition gsBase64.h:218
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition gsFunctionSet.h:219
virtual index_t nPieces() const
Number of pieces in the domain of definition.
Definition gsFunctionSet.h:619
gsMatrix< T > eval(const gsMatrix< T > &u) const
Evaluate the function,.
Definition gsFunctionSet.hpp:120
virtual short_t targetDim() const
Dimension of the target space.
Definition gsFunctionSet.h:595
virtual const gsFunctionSet & piece(const index_t) const
Returns the piece(s) of the function(s) at subdomain k.
Definition gsFunctionSet.h:239
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
#define index_t
Definition gsConfig.h:32
Provides the gsDofMapper class for re-indexing DoFs.
Generic expressions evaluator.
Generic expressions helper.
Provides declaration of the Field class.
Input and output Utilities.
This is the main header file that collects wrappers of Eigen for linear algebra.
Provides declaration of Basis abstract interface.
The G+Smo namespace, containing all definitions for the library.
gsMatrix< real_t > vtkIDTransform(index_t nU, index_t nV)
ID transformation between G+Smo and vtk control point IDs.
Definition gsParaviewUtils.cpp:23
std::vector< std::string > toVTK(const gsFunctionSet< T > &funSet, unsigned nPts=1000, unsigned precision=5, std::string label="", const bool &export_base64=false)
Evaluates gsFunctionSet over all pieces( patches ) and returns all <DataArray> xml tags as a vector o...
Definition gsParaviewUtils.hpp:35
std::string toDataArray(index_t num, std::map< std::string, std::string > attributes)
Converts an integer to a 'DataArray' xml tag, which is returned as a string.
Definition gsParaviewUtils.cpp:66