37 #ifndef GETFEM_EXPORT_H__
38 #define GETFEM_EXPORT_H__
52 inline std::string remove_spaces(
const std::string &s) {
54 for (
unsigned i=0; i < s.size(); ++i)
55 if (s2[i] <=
' ') s2[i] =
'_';
74 std::unique_ptr<mesh_fem> pmf;
75 dal::bit_vector pmf_dof_used;
76 std::vector<unsigned> pmf_mapping_type;
77 std::ofstream real_os;
80 std::vector<unsigned char> vals;
81 enum { EMPTY, HEADER_WRITTEN, STRUCTURE_WRITTEN, IN_CELL_DATA,
82 IN_POINT_DATA } state;
84 template<
class T>
void write_val(T v);
85 template<
class V>
void write_vec(V p,
size_type qdim);
86 template<
class IT>
void write_3x3tensor(IT p);
92 vtk_export(
const std::string& fname,
bool ascii_ =
false,
bool vtk_=
true);
93 vtk_export(std::ostream &os_,
bool ascii_ =
false,
bool vtk_ =
true);
116 const std::string& name);
123 const std::string& name,
130 const std::string& name,
141 void write_normals();
143 const mesh_fem& get_exported_mesh_fem()
const;
147 void write_mesh_structure_from_slice();
148 void write_mesh_structure_from_mesh_fem();
149 void switch_to_cell_data();
150 void switch_to_point_data();
151 template<
class VECT>
void write_dataset_(
const VECT& U,
152 const std::string& name,
154 bool cell_data=
false);
157 template<
class T>
void vtk_export::write_val(T v) {
158 if (ascii) os <<
" " << v;
163 for (
size_type i=0; i <
sizeof(v)/2; ++i)
164 std::swap(p[i], p[
sizeof(v)-i-1]);
165 os.write(p,
sizeof(T));
167 union { T value;
unsigned char bytes[
sizeof(T)]; } UNION;
170 vals.push_back(UNION.bytes[i]);
175 template<
class IT>
void vtk_export::write_vec(IT p,
size_type qdim) {
180 for (
size_type i=qdim; i < 3; ++i) v[i] = 0.0f;
181 write_val(v[0]);write_val(v[1]);write_val(v[2]);
184 template<
class IT>
void vtk_export::write_3x3tensor(IT p) {
186 memset(v, 0,
sizeof v);
189 v[i][j] =
float(p[i + j*dim_]);
195 if (ascii) os <<
"\n";
201 const std::string& name) {
205 std::vector<scalar_type> Uslice(Q*psl->
nb_points());
207 write_dataset_(Uslice, name, qdim);
209 std::vector<scalar_type> V(pmf->nb_dof() * Q);
210 if (&mf != &(*pmf)) {
212 }
else gmm::copy(U,V);
214 for (dal::bv_visitor d(pmf_dof_used); !d.finished(); ++d, ++cnt) {
217 V[cnt*Q + q] = V[d*Q + q];
220 V.resize(Q*pmf_dof_used.card());
221 write_dataset_(V, name, qdim);
228 write_dataset_(U, name, qdim,
true);
233 const std::string& name,
235 write_dataset_(U, name, qdim,
false);
239 void vtk_export::write_dataset_(
const VECT& U,
const std::string& name,
244 switch_to_cell_data();
246 : pmf->linked_mesh().convex_index().card();
248 switch_to_point_data();
249 nb_val = psl ? psl->
nb_points() : pmf_dof_used.card();
252 if (Q == 1) Q = gmm::vect_size(U) / nb_val;
253 GMM_ASSERT1(gmm::vect_size(U) == nb_val*Q,
254 "inconsistency in the size of the dataset: "
255 << gmm::vect_size(U) <<
" != " << nb_val <<
"*" << Q);
256 if (vtk) write_separ();
257 if (!vtk && !ascii) write_val(
float(gmm::vect_size(U)));
260 os <<
"SCALARS " << remove_spaces(name) <<
" float 1\n"
261 <<
"LOOKUP_TABLE default\n";
263 os <<
"<DataArray type=\"Float32\" Name=\"" << remove_spaces(name) <<
"\" "
264 << (ascii ?
"format=\"ascii\">\n" :
"format=\"binary\">\n");
266 write_val(
float(U[i]));
269 os <<
"VECTORS " << remove_spaces(name) <<
" float\n";
271 os <<
"<DataArray type=\"Float32\" Name=\"" << remove_spaces(name) <<
"\" "
272 <<
"NumberOfComponents=\"3\" "
273 << (ascii ?
"format=\"ascii\">\n" :
"format=\"binary\">\n");
275 write_vec(U.begin() + i*Q, Q);
276 }
else if (Q == gmm::sqr(dim_)) {
281 os <<
"TENSORS " << remove_spaces(name) <<
" float\n";
283 os <<
"<DataArray type=\"Float32\" Name=\"" << remove_spaces(name)
284 <<
"\" NumberOfComponents=\"9\" "
285 << (ascii ?
"format=\"ascii\">\n" :
"format=\"binary\">\n");
287 write_3x3tensor(U.begin() + i*Q);
289 GMM_ASSERT1(
false, std::string(vtk ?
"vtk" :
"vtu")
290 +
" does not accept vectors of dimension > 3");
292 if (vtk) write_separ();
293 if (!vtk) os <<
"\n" <<
"</DataArray>\n";
297 class vtu_export :
public vtk_export {
299 vtu_export(
const std::string& fname,
bool ascii_ =
false) : vtk_export(fname, ascii_, false) {}
300 vtu_export(std::ostream &os_,
bool ascii_ =
false) : vtk_export(os_, ascii_, false) {}
324 std::unique_ptr<mesh_fem> pmf;
325 dal::bit_vector pmf_dof_used;
326 std::vector<unsigned> pmf_cell_type;
327 std::fstream real_os;
328 dim_type dim_, connections_dim;
331 std::list<std::string> members;
339 typedef enum { NONE=0, WITH_EDGES=1, STRUCTURE_WRITTEN=2 } flags_t;
341 dxMesh() : flags(NONE) {}
343 std::list<dxObject> objects;
344 std::list<dxSeries> series;
345 std::list<dxMesh> meshes;
348 dx_export(
const std::string& fname,
bool ascii_ =
false,
349 bool append_ =
false);
350 dx_export(std::ostream &os_,
bool ascii_ =
false);
353 void exporting(
const mesh& m, std::string name = std::string());
354 void exporting(
const mesh_fem& mf, std::string name = std::string());
356 std::string name = std::string());
375 const std::string& object_name);
383 template<
class VECT>
void
385 const VECT& U0, std::string name = std::string());
386 template<
class VECT>
void
387 write_sliced_point_data(
const VECT& Uslice,
388 std::string name = std::string());
393 void write_normals();
395 const mesh_fem& get_exported_mesh_fem()
const;
399 void reread_metadata();
400 void update_metadata(std::ios::pos_type);
402 void serie_add_object_(
const std::string &serie_name,
403 const std::string &object_name);
405 std::string default_name(std::string s,
int count,
406 const char *default_prefix) {
408 std::stringstream ss; ss << default_prefix << count;
return ss.str();
411 template<
class T>
void write_val(T v) {
412 if (ascii) os <<
" " << v;
413 else os.write((
char*)&v,
sizeof(T));
415 static const char* endianness() {
416 static int i=0x12345678;
418 if (*p == 0x12)
return "msb";
419 else if (*p == 0x78)
return "lsb";
420 else return "this is very strange..";
422 bool new_mesh(std::string &name);
423 std::list<dxMesh>::iterator get_mesh(
const std::string& name,
424 bool raise_error =
true);
425 std::list<dxObject>::iterator get_object(
const std::string& name,
426 bool raise_error =
true);
427 dxMesh ¤t_mesh() {
428 if (meshes.size())
return meshes.back();
429 else GMM_ASSERT1(
false,
"no mesh!");
431 dxObject ¤t_data() {
432 if (objects.size())
return objects.back();
433 else GMM_ASSERT1(
false,
"no data!");
436 std::string name_of_pts_array(
const std::string &meshname)
437 {
return meshname + std::string(
"_pts"); }
438 std::string name_of_conn_array(
const std::string &meshname)
439 {
return meshname + std::string(
"_conn"); }
440 std::string name_of_edges_array(
const std::string &meshname)
441 {
return meshname + std::string(
"_edges"); }
445 void write_mesh_structure_from_slice();
446 void write_mesh_structure_from_mesh_fem();
447 void write_mesh_edges_from_slice(
bool with_slice_edge);
448 void write_mesh_edges_from_mesh();
449 template <
class VECT>
450 void smooth_field(
const VECT& U, base_vector &sU);
452 void write_dataset_(
const VECT& U, std::string name,
bool cell_data=
false);
455 template <
class VECT>
456 void dx_export::smooth_field(
const VECT& U, base_vector &sU) {
462 sU[i*Q+q] += U[psl->merged_point_nodes(i)[j].pos*Q+q];
473 std::vector<scalar_type> Uslice(Q*psl->
nb_points());
475 write_sliced_point_data(Uslice,name);
477 std::vector<scalar_type> V(pmf->nb_dof() * Q);
478 if (&mf != &(*pmf)) {
482 for (dal::bv_visitor d(pmf_dof_used); !d.finished(); ++d, ++cnt) {
485 V[cnt*Q + q] = V[d*Q + q];
488 V.resize(Q*pmf_dof_used.card());
489 write_dataset_(V, name);
493 template<
class VECT>
void
494 dx_export::write_sliced_point_data(
const VECT& Uslice, std::string name) {
496 write_dataset_(Uslice, name,
false);
498 base_vector Umerged; smooth_field(Uslice,Umerged);
499 write_dataset_(Umerged, name,
false);
503 template<
class VECT>
void
504 dx_export::write_dataset_(
const VECT& U, std::string name,
bool cell_data) {
506 objects.push_back(dxObject());
507 name = default_name(name,
int(objects.size()),
"gf_field");
508 objects.back().name = name;
513 : pmf->linked_mesh().convex_index().card();
516 : pmf_dof_used.card();
518 size_type Q = gmm::vect_size(U) / nb_val;
519 GMM_ASSERT1(gmm::vect_size(U) == nb_val*Q,
520 "inconsistency in the size of the dataset: "
521 << gmm::vect_size(U) <<
" != " << nb_val <<
"*" << Q);
523 os <<
"\nobject \"" << name <<
"_data\" class array type float rank ";
524 if (Q == 1) { os <<
"0"; }
525 else if (Q == 4) { os <<
"2 shape 2 2"; }
526 else if (Q == 9) { os <<
"2 shape 3 3"; }
527 else { os <<
"1 shape " << Q; }
528 os <<
" items " << nb_val;
529 if (!ascii) os <<
" " << endianness() <<
" binary";
530 os <<
" data follows" << endl;
532 write_val(
float(U[i]));
533 if (((i+1) % (Q > 1 ? Q : 10)) == 0) write_separ();
538 os <<
"\n attribute \"dep\" string \"positions\"\n";
539 else os <<
"\n attribute \"dep\" string \"connections\"\n";
542 if (current_mesh().flags & dxMesh::WITH_EDGES) {
543 os <<
"\nobject \"" << name <<
"_edges\" class field\n"
544 <<
" component \"positions\" value \""
546 <<
" component \"connections\" value \""
549 <<
" component \"data\" value \"" << name <<
"_data\"\n";
553 os <<
"\nobject \"" << name <<
"\" class field\n"
554 <<
" component \"positions\" value \""
556 <<
" component \"connections\" value \""
558 <<
" component \"data\" value \"" << name <<
"_data\"\n";
575 std::vector<std::vector<float> > pos_pts;
576 std::vector<unsigned> pos_cell_type;
577 std::vector<std::vector<unsigned> > pos_cell_dof;
579 std::unique_ptr<mesh_fem> pmf;
584 enum { EMPTY, HEADER_WRITTEN, STRUCTURE_WRITTEN, IN_CELL_DATA } state;
585 std::ofstream real_os;
602 void set_header(
const std::string& s);
604 void exporting(
const mesh& m);
608 void write(
const mesh& m,
const std::string& name=
"");
609 void write(
const mesh_fem& mf,
const std::string& name=
"");
612 template <
class VECT>
613 void write(
const mesh_fem& mf,
const VECT& U,
const std::string& name);
614 template <
class VECT>
621 template <
class VECT>
622 void write(
const VECT& V,
const size_type qdim_v);
624 template <
class VECT>
625 void write_cell(
const int& t,
const std::vector<unsigned>& dof,
629 template <
class VECT>
630 void pos_export::write(
const mesh_fem& mf,
const VECT& U,
631 const std::string& name){
635 os <<
"View \"" << name.c_str() <<
"\" {\n";
638 size_type qdim_u = gmm::vect_size(U)/nb_points;
640 std::vector<scalar_type> Uslice(psl->
nb_points()*qdim_u);
642 qdim_u = gmm::vect_size(Uslice)/psl->
nb_points();
643 write(Uslice, qdim_u);
645 std::vector<scalar_type> V(pmf->nb_dof()*qdim_u);
646 if (&mf != &(*pmf)) {
656 nb_points = pmf->nb_dof()/pmf->get_qdim();
657 qdim_u = gmm::vect_size(V)/nb_points;
662 os <<
"View[" << view <<
"].ShowScale = 1;\n";
663 os <<
"View[" << view <<
"].ShowElement = 0;\n";
664 os <<
"View[" << view <<
"].DrawScalars = 1;\n";
665 os <<
"View[" << view <<
"].DrawVectors = 1;\n";
666 os <<
"View[" << view++ <<
"].DrawTensors = 1;\n";
669 template <
class VECT>
670 void pos_export::write(
const stored_mesh_slice& sl,
const VECT& V,
671 const std::string& name){
675 os <<
"View \"" << name.c_str() <<
"\" {\n";
681 os <<
"View[" << view <<
"].ShowScale = 1;\n";
682 os <<
"View[" << view <<
"].ShowElement = 0;\n";
683 os <<
"View[" << view <<
"].DrawScalars = 1;\n";
684 os <<
"View[" << view <<
"].DrawVectors = 1;\n";
685 os <<
"View[" << view++ <<
"].DrawTensors = 1;\n";
688 template <
class VECT>
689 void pos_export::write(
const VECT& V,
const size_type qdim_v) {
691 std::vector<unsigned> cell_dof;
692 std::vector<scalar_type> cell_dof_val;
693 for (
size_type cell = 0; cell < pos_cell_type.size(); ++cell) {
694 t = pos_cell_type[cell];
695 cell_dof = pos_cell_dof[cell];
696 cell_dof_val.resize(cell_dof.size()*qdim_v, scalar_type(0));
697 for (
size_type i=0; i< cell_dof.size(); ++i)
699 cell_dof_val[i*qdim_v+j] = scalar_type(V[cell_dof[i]*qdim_v+j]);
700 write_cell(t,cell_dof,cell_dof_val);
704 template <
class VECT>
705 void pos_export::write_cell(
const int& t,
const std::vector<unsigned>& dof,
707 size_type qdim_cell = val.size()/dof.size();
712 }
else if (2==qdim_cell || 3==qdim_cell){
715 }
else if (4<=qdim_cell && qdim_cell<=9){
720 case POS_PT: os <<
"P(";
break;
721 case POS_LN: os <<
"L(";
break;
722 case POS_TR: os <<
"T(";
break;
723 case POS_QU: os <<
"Q(";
break;
724 case POS_SI: os <<
"S(";
break;
725 case POS_HE: os <<
"H(";
break;
726 case POS_PR: os <<
"I(";
break;
727 case POS_PY: os <<
"Y(";
break;
731 if(0!=i || 0!=j) os <<
",";
732 os << pos_pts[dof[i]][j];
742 if(0!=i || 0!=j) os <<
",";
743 os << val[i*qdim_cell+j];
745 for (
size_type j=qdim_cell; j< dim3D; ++j){
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
A (quite large) class for exportation of data to IBM OpenDX.
std::string current_mesh_name()
return the name of current mesh (use exporting(...) to change the current mesh)
void serie_add_object(const std::string &serie_name, const std::string &object_name)
add an object (typically the name of a data field) to a 'series', i.e.
std::string current_data_name()
return the name of last written data_set
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 this...
void exporting_mesh_edges(bool with_slice_edge=true)
append edges information (if you want to draw the mesh and are using a refined slice.
Describe a finite element method linked to a mesh.
virtual dim_type get_qdim() const
Return the Q dimension.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
Describe a mesh (collection of convexes (elements) and points).
The output of a getfem::mesh_slicer which has been recorded.
size_type merged_point_cnt(size_type i_merged) const
Return the number of nodes that were merged to form the merged one.
const mesh & linked_mesh() const
return a pointer to the original mesh
size_type nb_points() const
Return the number of nodes in the slice.
void interpolate(const getfem::mesh_fem &mf, const V1 &UU, V2 &V) const
Interpolation of a mesh_fem on a slice.
size_type nb_merged_nodes() const
Return the number of merged nodes in 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 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 this...
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/.vtu file.
void write_cell_data(const VECT &U, const std::string &name, size_type qdim=1)
export data which is constant over each element.
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.
Interpolation of fields from a mesh_fem onto another.
Define the class getfem::stored_mesh_slice.
void copy(const L1 &l1, L2 &l2)
*/
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
GEneric Tool for Finite Element Methods.
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.