38 #ifndef GETFEM_EXPORT_H__ 39 #define GETFEM_EXPORT_H__ 53 inline std::string remove_spaces(
const std::string &s) {
55 for (
unsigned i=0; i < s.size(); ++i)
56 if (s2[i] <=
' ') s2[i] =
'_';
73 std::unique_ptr<mesh_fem> pmf;
74 dal::bit_vector pmf_dof_used;
75 std::vector<unsigned> pmf_mapping_type;
76 std::ofstream real_os;
79 enum { EMPTY, HEADER_WRITTEN, STRUCTURE_WRITTEN, IN_CELL_DATA,
80 IN_POINT_DATA } state;
82 template<
class T>
void write_val(T v);
83 template<
class V>
void write_vec(V p,
size_type qdim);
84 template<
class IT>
void write_3x3tensor(IT p);
88 typedef enum { VTK_VERTEX = 1,
98 VTK_QUADRATIC_EDGE = 21,
99 VTK_QUADRATIC_TRIANGLE = 22,
100 VTK_QUADRATIC_QUAD = 23,
101 VTK_QUADRATIC_TETRA = 24,
102 VTK_QUADRATIC_HEXAHEDRON = 25,
103 VTK_QUADRATIC_WEDGE = 26,
104 VTK_QUADRATIC_PYRAMID = 27,
105 VTK_BIQUADRATIC_QUAD = 28,
106 VTK_TRIQUADRATIC_HEXAHEDRON = 29,
107 VTK_BIQUADRATIC_QUADRATIC_WEDGE = 32 } vtk_cell_type;
108 vtk_export(
const std::string& fname,
bool ascii_ =
false);
109 vtk_export(std::ostream &os_,
bool ascii_ =
false);
132 const std::string& name);
139 const std::string& name,
146 const std::string& name,
157 void write_normals();
159 const mesh_fem& get_exported_mesh_fem()
const;
163 void write_mesh_structure_from_slice();
164 void write_mesh_structure_from_mesh_fem();
165 void switch_to_cell_data();
166 void switch_to_point_data();
167 template<
class VECT>
void write_dataset_(
const VECT& U,
168 const std::string& name,
170 bool cell_data=
false);
173 template<
class T>
void vtk_export::write_val(T v) {
174 if (ascii) os <<
" " << v;
178 for (
size_type i=0; i <
sizeof(v)/2; ++i)
179 std::swap(p[i], p[
sizeof(v)-i-1]);
180 os.write(p,
sizeof(T));
184 template<
class IT>
void vtk_export::write_vec(IT p,
size_type qdim) {
189 for (
size_type i=qdim; i < 3; ++i) v[i] = 0.0f;
190 write_val(v[0]);write_val(v[1]);write_val(v[2]);
193 template<
class IT>
void vtk_export::write_3x3tensor(IT p) {
195 memset(v, 0,
sizeof v);
198 v[i][j] =
float(p[i + j*dim_]);
204 if (ascii) os <<
"\n";
210 const std::string& name) {
214 std::vector<scalar_type> Uslice(Q*psl->
nb_points());
216 write_dataset_(Uslice, name, qdim);
218 std::vector<scalar_type> V(pmf->nb_dof() * Q);
219 if (&mf != &(*pmf)) {
221 }
else gmm::copy(U,V);
223 for (dal::bv_visitor d(pmf_dof_used); !d.finished(); ++d, ++cnt) {
226 V[cnt*Q + q] = V[d*Q + q];
229 V.resize(Q*pmf_dof_used.card());
230 write_dataset_(V, name, qdim);
237 write_dataset_(U, name, qdim,
true);
242 const std::string& name,
244 write_dataset_(U, name, qdim,
false);
248 void vtk_export::write_dataset_(
const VECT& U,
const std::string& name,
253 switch_to_cell_data();
255 : pmf->linked_mesh().convex_index().card();
257 switch_to_point_data();
258 nb_val = psl ? psl->
nb_points() : pmf_dof_used.card();
261 if (Q == 1) Q = gmm::vect_size(U) / nb_val;
262 GMM_ASSERT1(gmm::vect_size(U) == nb_val*Q,
263 "inconsistency in the size of the dataset: " 264 << gmm::vect_size(U) <<
" != " << nb_val <<
"*" << Q);
267 os <<
"SCALARS " << remove_spaces(name) <<
" float 1\n";
268 os <<
"LOOKUP_TABLE default\n";
270 write_val(
float(U[i]));
273 os <<
"VECTORS " << remove_spaces(name) <<
" float\n";
275 write_vec(U.begin() + i*Q, Q);
277 }
else if (Q == gmm::sqr(dim_)) {
281 os <<
"TENSORS " << remove_spaces(name) <<
" float\n";
283 write_3x3tensor(U.begin() + i*Q);
285 }
else GMM_ASSERT1(
false,
"vtk does not accept vectors of dimension > 3");
311 std::unique_ptr<mesh_fem> pmf;
312 dal::bit_vector pmf_dof_used;
313 std::vector<unsigned> pmf_cell_type;
314 std::fstream real_os;
315 dim_type dim_, connections_dim;
318 std::list<std::string> members;
326 typedef enum { NONE=0, WITH_EDGES=1, STRUCTURE_WRITTEN=2 } flags_t;
328 dxMesh() : flags(NONE) {}
330 std::list<dxObject> objects;
331 std::list<dxSeries> series;
332 std::list<dxMesh> meshes;
335 dx_export(
const std::string& fname,
bool ascii_ =
false,
336 bool append_ =
false);
337 dx_export(std::ostream &os_,
bool ascii_ =
false);
340 void exporting(
const mesh& m, std::string name = std::string());
343 std::string name = std::string());
346 void exporting_mesh_edges(
bool with_slice_edge =
true);
361 void serie_add_object(
const std::string& serie_name,
362 const std::string& object_name);
363 void serie_add_object(
const std::string& serie_name)
364 { serie_add_object(serie_name, current_data_name()); }
370 template<
class VECT>
void 372 const VECT& U0, std::string name = std::string());
373 template<
class VECT>
void 375 std::string name = std::string());
380 void write_normals();
382 const mesh_fem& get_exported_mesh_fem()
const;
386 void reread_metadata();
387 void update_metadata(std::ios::pos_type);
389 void serie_add_object_(
const std::string &serie_name,
390 const std::string &object_name);
392 std::string default_name(std::string s,
int count,
393 const char *default_prefix) {
395 std::stringstream ss; ss << default_prefix << count;
return ss.str();
398 template<
class T>
void write_val(T v) {
399 if (ascii) os <<
" " << v;
400 else os.write((
char*)&v,
sizeof(T));
402 static const char* endianness() {
403 static int i=0x12345678;
405 if (*p == 0x12)
return "msb";
406 else if (*p == 0x78)
return "lsb";
407 else return "this is very strange..";
409 bool new_mesh(std::string &name);
410 std::list<dxMesh>::iterator get_mesh(
const std::string& name,
411 bool raise_error =
true);
412 std::list<dxObject>::iterator get_object(
const std::string& name,
413 bool raise_error =
true);
414 dxMesh ¤t_mesh() {
415 if (meshes.size())
return meshes.back();
416 else GMM_ASSERT1(
false,
"no mesh!");
418 dxObject ¤t_data() {
419 if (objects.size())
return objects.back();
420 else GMM_ASSERT1(
false,
"no data!");
423 std::string name_of_pts_array(
const std::string &meshname)
424 {
return meshname + std::string(
"_pts"); }
425 std::string name_of_conn_array(
const std::string &meshname)
426 {
return meshname + std::string(
"_conn"); }
427 std::string name_of_edges_array(
const std::string &meshname)
428 {
return meshname + std::string(
"_edges"); }
432 void write_mesh_structure_from_slice();
433 void write_mesh_structure_from_mesh_fem();
434 void write_mesh_edges_from_slice(
bool with_slice_edge);
435 void write_mesh_edges_from_mesh();
436 template <
class VECT>
437 void smooth_field(
const VECT& U, base_vector &sU);
439 void write_dataset_(
const VECT& U, std::string name,
bool cell_data=
false);
442 template <
class VECT>
443 void dx_export::smooth_field(
const VECT& U, base_vector &sU) {
444 size_type Q = gmm::vect_size(U) / psl->nb_points();
445 sU.clear(); sU.resize(Q*psl->nb_merged_nodes());
446 for (
size_type i=0; i < psl->nb_merged_nodes(); ++i) {
447 for (
size_type j=0; j < psl->merged_point_cnt(i); ++j)
449 sU[i*Q+q] += U[psl->merged_point_nodes(i)[j].pos*Q+q];
451 sU[i*Q+q] /=
double(psl->merged_point_cnt(i));
460 std::vector<scalar_type> Uslice(Q*psl->nb_points());
461 psl->interpolate(mf, U, Uslice);
464 std::vector<scalar_type> V(pmf->nb_dof() * Q);
465 if (&mf != &(*pmf)) {
467 }
else gmm::copy(U,V);
469 for (dal::bv_visitor d(pmf_dof_used); !d.finished(); ++d, ++cnt) {
472 V[cnt*Q + q] = V[d*Q + q];
475 V.resize(Q*pmf_dof_used.card());
476 write_dataset_(V, name);
480 template<
class VECT>
void 481 dx_export::write_sliced_point_data(
const VECT& Uslice, std::string name) {
483 write_dataset_(Uslice, name,
false);
485 base_vector Umerged; smooth_field(Uslice,Umerged);
486 write_dataset_(Umerged, name,
false);
490 template<
class VECT>
void 491 dx_export::write_dataset_(
const VECT& U, std::string name,
bool cell_data) {
493 objects.push_back(dxObject());
494 name = default_name(name,
int(objects.size()),
"gf_field");
495 objects.back().name = name;
496 objects.back().mesh = current_mesh_name();
499 nb_val = psl ? psl->linked_mesh().convex_index().card()
500 : pmf->linked_mesh().convex_index().card();
502 nb_val = psl ? (psl_use_merged ? psl->nb_merged_nodes() : psl->nb_points())
503 : pmf_dof_used.card();
505 size_type Q = gmm::vect_size(U) / nb_val;
506 GMM_ASSERT1(gmm::vect_size(U) == nb_val*Q,
507 "inconsistency in the size of the dataset: " 508 << gmm::vect_size(U) <<
" != " << nb_val <<
"*" << Q);
510 os <<
"\nobject \"" << name <<
"_data\" class array type float rank ";
511 if (Q == 1) { os <<
"0"; }
512 else if (Q == 4) { os <<
"2 shape 2 2"; }
513 else if (Q == 9) { os <<
"2 shape 3 3"; }
514 else { os <<
"1 shape " << Q; }
515 os <<
" items " << nb_val;
516 if (!ascii) os <<
" " << endianness() <<
" binary";
517 os <<
" data follows" << endl;
519 write_val(
float(U[i]));
520 if (((i+1) % (Q > 1 ? Q : 10)) == 0) write_separ();
525 os <<
"\n attribute \"dep\" string \"positions\"\n";
526 else os <<
"\n attribute \"dep\" string \"connections\"\n";
529 if (current_mesh().flags & dxMesh::WITH_EDGES) {
530 os <<
"\nobject \"" << name <<
"_edges\" class field\n" 531 <<
" component \"positions\" value \"" 532 << name_of_pts_array(current_mesh_name()) <<
"\"\n" 533 <<
" component \"connections\" value \"" 534 << name_of_conn_array(name_of_edges_array(current_mesh_name()))
536 <<
" component \"data\" value \"" << name <<
"_data\"\n";
540 os <<
"\nobject \"" << name <<
"\" class field\n" 541 <<
" component \"positions\" value \"" 542 << name_of_pts_array(current_mesh_name()) <<
"\"\n" 543 <<
" component \"connections\" value \"" 544 << name_of_conn_array(current_mesh_name()) <<
"\"\n" 545 <<
" component \"data\" value \"" << name <<
"_data\"\n";
562 std::vector<std::vector<float> > pos_pts;
563 std::vector<unsigned> pos_cell_type;
564 std::vector<std::vector<unsigned> > pos_cell_dof;
566 std::unique_ptr<mesh_fem> pmf;
571 enum { EMPTY, HEADER_WRITTEN, STRUCTURE_WRITTEN, IN_CELL_DATA} state;
572 std::ofstream real_os;
595 void write(
const mesh& m,
const std::string& name=
"");
596 void write(
const mesh_fem& mf,
const std::string& name=
"");
599 template <
class VECT>
600 void write(
const mesh_fem& mf,
const VECT& U,
const std::string& name);
601 template <
class VECT>
608 template <
class VECT>
609 void write(
const VECT& V,
const size_type qdim_v);
611 template <
class VECT>
612 void write_cell(
const int& t,
const std::vector<unsigned>& dof,
616 template <
class VECT>
617 void pos_export::write(
const mesh_fem& mf,
const VECT& U,
618 const std::string& name){
622 os <<
"View \"" << name.c_str() <<
"\" {\n";
625 size_type qdim_u = gmm::vect_size(U)/nb_points;
627 std::vector<scalar_type> Uslice(psl->nb_points()*qdim_u);
628 psl->interpolate(mf, U, Uslice);
629 qdim_u = gmm::vect_size(Uslice)/psl->nb_points();
630 write(Uslice, qdim_u);
632 std::vector<scalar_type> V(pmf->nb_dof()*qdim_u);
633 if (&mf != &(*pmf)) {
635 }
else gmm::copy(U,V);
643 nb_points = pmf->nb_dof()/pmf->get_qdim();
644 qdim_u = gmm::vect_size(V)/nb_points;
649 os <<
"View[" << view <<
"].ShowScale = 1;\n";
650 os <<
"View[" << view <<
"].ShowElement = 0;\n";
651 os <<
"View[" << view <<
"].DrawScalars = 1;\n";
652 os <<
"View[" << view <<
"].DrawVectors = 1;\n";
653 os <<
"View[" << view++ <<
"].DrawTensors = 1;\n";
656 template <
class VECT>
658 const std::string& name){
662 os <<
"View \"" << name.c_str() <<
"\" {\n";
664 size_type qdim_v = gmm::vect_size(V)/psl->nb_points();
668 os <<
"View[" << view <<
"].ShowScale = 1;\n";
669 os <<
"View[" << view <<
"].ShowElement = 0;\n";
670 os <<
"View[" << view <<
"].DrawScalars = 1;\n";
671 os <<
"View[" << view <<
"].DrawVectors = 1;\n";
672 os <<
"View[" << view++ <<
"].DrawTensors = 1;\n";
675 template <
class VECT>
676 void pos_export::write(
const VECT& V,
const size_type qdim_v) {
678 std::vector<unsigned> cell_dof;
679 std::vector<scalar_type> cell_dof_val;
680 for (
size_type cell = 0; cell < pos_cell_type.size(); ++cell) {
681 t = pos_cell_type[cell];
682 cell_dof = pos_cell_dof[cell];
683 cell_dof_val.resize(cell_dof.size()*qdim_v, scalar_type(0));
684 for (
size_type i=0; i< cell_dof.size(); ++i)
686 cell_dof_val[i*qdim_v+j] = scalar_type(V[cell_dof[i]*qdim_v+j]);
687 write_cell(t,cell_dof,cell_dof_val);
691 template <
class VECT>
692 void pos_export::write_cell(
const int& t,
const std::vector<unsigned>& dof,
694 size_type qdim_cell = val.size()/dof.size();
699 }
else if (2==qdim_cell || 3==qdim_cell){
702 }
else if (4<=qdim_cell && qdim_cell<=9){
707 case POS_PT: os <<
"P(";
break;
708 case POS_LN: os <<
"L(";
break;
709 case POS_TR: os <<
"T(";
break;
710 case POS_QU: os <<
"Q(";
break;
711 case POS_SI: os <<
"S(";
break;
712 case POS_HE: os <<
"H(";
break;
713 case POS_PR: os <<
"I(";
break;
714 case POS_PY: os <<
"Y(";
break;
718 if(0!=i || 0!=j) os <<
",";
719 os << pos_pts[dof[i]][j];
729 if(0!=i || 0!=j) os <<
",";
730 os << val[i*qdim_cell+j];
732 for (
size_type j=qdim_cell; j< dim3D; ++j){
const mesh & linked_mesh() const
return a pointer to the original mesh
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
void set_header(const std::string &s)
the header is the second line of text in the exported file, you can put whatever you want – call thi...
size_type nb_points() const
Return the number of nodes in the slice.
void interpolation(const mesh_fem &mf_source, const mesh_fem &mf_target, const VECTU &U, VECTV &V, int extrapolation=0, double EPS=1E-10, mesh_region rg_source=mesh_region::all_convexes(), mesh_region rg_target=mesh_region::all_convexes())
interpolation/extrapolation of (mf_source, U) on mf_target.
std::string current_mesh_name()
return the name of current mesh (use exporting(...) to change the current mesh)
std::string current_data_name()
return the name of last written data_set
Describe a mesh (collection of convexes (elements) and points).
void exporting(const mesh &m)
should be called before write_*_data
void write_sliced_point_data(const VECT &Uslice, const std::string &name, size_type qdim=1)
append a new scalar or vector field to .vtk file.
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
size_t size_type
used as the common size type in the library
void write_point_data(const getfem::mesh_fem &mf, const VECT &U0, const std::string &name)
append a new scalar or vector field defined on mf to the .vtk file.
Interpolation of fields from a mesh_fem onto another.
virtual dim_type get_qdim() const
Return the Q dimension.
void interpolate(const getfem::mesh_fem &mf, const V1 &UU, V2 &V) const
Interpolation of a mesh_fem on a slice.
The output of a getfem::mesh_slicer which has been recorded.
A (quite large) class for exportation of data to IBM OpenDX.
GEneric Tool for Finite Element Methods.
Describe a finite element method linked to a mesh.
Define the class getfem::stored_mesh_slice.
void write_mesh_quality(const mesh &m)
export a data_set correspounding to measures of quality for each convex of the supplied mesh (which s...
void write_cell_data(const VECT &U, const std::string &name, size_type qdim=1)
export data which is constant over each element.
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.