32   template<
typename C> 
static bool check_voxel(
const C& c) {
 
   34     unsigned N = c[0].size();
 
   35     if (c.size() != (1U << N)) 
return false;
 
   36     const base_node P0 = c[0];
 
   37     h[0] = c[1][0] - P0[0];
 
   38     h[1] = c[2][0] - P0[0];
 
   39     if (c.size() != 4) h[2] = c[4][0] - P0[0];
 
   40     for (
unsigned i=1; i < c.size(); ++i) {
 
   41       const base_node d = c[i] - P0;
 
   42       for (
unsigned j=0; j < N; ++j)
 
   43         if (gmm::abs(d[j]) > 1e-7*h[j] && gmm::abs(d[j] - h[j]) > 1e-7*h[j])
 
   50   std::string base64_encode(
const std::vector<unsigned char>& src)
 
   52     const std::string table(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
 
   54     for (
size_type i = 0; i < src.size(); ++i) {
 
   57         dst.push_back(table[(src[i] & 0xFC) >> 2]);
 
   58         if (i + 1 == src.size()) {
 
   59           dst.push_back(table[(src[i] & 0x03) << 4]);
 
   65         dst.push_back(table[((src[i - 1] & 0x03) << 4) | ((src[i + 0] & 0xF0) >> 4)]);
 
   66         if (i + 1 == src.size()) {
 
   67           dst.push_back(table[(src[i] & 0x0F) << 2]);
 
   72         dst.push_back(table[((src[i - 1] & 0x0F) << 2) | ((src[i + 0] & 0xC0) >> 6)]);
 
   73         dst.push_back(table[src[i] & 0x3F]);
 
   84   struct gf2vtk_dof_mapping : 
public std::vector<std::vector<unsigned> > {};
 
   85   struct gf2vtk_vtk_type : 
public std::vector<int> {};
 
   87   typedef enum { VTK_VERTEX = 1,
 
   97                  VTK_QUADRATIC_EDGE = 21,
 
   98                  VTK_QUADRATIC_TRIANGLE = 22,
 
   99                  VTK_QUADRATIC_QUAD = 23,
 
  100                  VTK_QUADRATIC_TETRA = 24,
 
  101                  VTK_QUADRATIC_HEXAHEDRON = 25,
 
  102                  VTK_QUADRATIC_WEDGE = 26,
 
  103                  VTK_QUADRATIC_PYRAMID = 27,
 
  104                  VTK_BIQUADRATIC_QUAD = 28,
 
  105                  VTK_TRIQUADRATIC_HEXAHEDRON = 29,
 
  106                  VTK_BIQUADRATIC_QUADRATIC_WEDGE = 32 } vtk_cell_type;
 
  108   typedef enum { NO_VTK_MAPPING,
 
  116                  N8_TO_VTK_HEXAHEDRON,
 
  119                  N3_TO_VTK_QUADRATIC_EDGE,
 
  120                  N6_TO_VTK_QUADRATIC_TRIANGLE,
 
  121                  N8_TO_VTK_QUADRATIC_QUAD,
 
  122                  N10_TO_VTK_QUADRATIC_TETRA,
 
  123                  N20_TO_VTK_QUADRATIC_HEXAHEDRON,
 
  124                  N15_TO_VTK_QUADRATIC_WEDGE,
 
  125                  N13_TO_VTK_QUADRATIC_PYRAMID,
 
  126                  N14_TO_VTK_QUADRATIC_PYRAMID,
 
  127                  N9_TO_VTK_BIQUADRATIC_QUAD,
 
  128                  N27_TO_VTK_TRIQUADRATIC_HEXAHEDRON,
 
  129                  N18_TO_VTK_BIQUADRATIC_QUADRATIC_WEDGE } vtk_mapping_type;
 
  141     vtktypes[N1_TO_VTK_VERTEX] = VTK_VERTEX;
 
  142     vtkmaps [N1_TO_VTK_VERTEX] = {0};
 
  143     vtktypes[N2_TO_VTK_LINE] = VTK_LINE;
 
  144     vtkmaps [N2_TO_VTK_LINE] = {0, 1};
 
  145     vtktypes[N3_TO_VTK_TRIANGLE] = VTK_TRIANGLE;
 
  146     vtkmaps [N3_TO_VTK_TRIANGLE] = {0, 1, 2};
 
  147     vtktypes[N4_TO_VTK_PIXEL] = VTK_PIXEL;
 
  148     vtkmaps [N4_TO_VTK_PIXEL] = {0, 1, 2, 3};
 
  149     vtktypes[N4_TO_VTK_QUAD] = VTK_QUAD;
 
  150     vtkmaps [N4_TO_VTK_QUAD] = {0, 1, 3, 2};
 
  151     vtktypes[N4_TO_VTK_TETRA] = VTK_TETRA;
 
  152     vtkmaps [N4_TO_VTK_TETRA] = {0, 1, 2, 3};
 
  153     vtktypes[N8_TO_VTK_VOXEL] = VTK_VOXEL;
 
  154     vtkmaps [N8_TO_VTK_VOXEL] = {0, 1, 2, 3, 4, 5, 6, 7};
 
  155     vtktypes[N8_TO_VTK_HEXAHEDRON] = VTK_HEXAHEDRON;
 
  156     vtkmaps [N8_TO_VTK_HEXAHEDRON] = {0, 1, 3, 2, 4, 5, 7, 6};
 
  157     vtktypes[N6_TO_VTK_WEDGE] = VTK_WEDGE;
 
  158     vtkmaps [N6_TO_VTK_WEDGE] = {0, 1, 2, 3, 4, 5};
 
  159     vtktypes[N5_TO_VTK_PYRAMID] = VTK_PYRAMID;
 
  160     vtkmaps [N5_TO_VTK_PYRAMID] = {0, 1, 3, 2, 4};
 
  161     vtktypes[N3_TO_VTK_QUADRATIC_EDGE] = VTK_QUADRATIC_EDGE;
 
  162     vtkmaps [N3_TO_VTK_QUADRATIC_EDGE] = {0, 2, 1};
 
  163     vtktypes[N6_TO_VTK_QUADRATIC_TRIANGLE] = VTK_QUADRATIC_TRIANGLE;
 
  164     vtkmaps [N6_TO_VTK_QUADRATIC_TRIANGLE] = {0, 2, 5, 1, 4, 3};
 
  165     vtktypes[N8_TO_VTK_QUADRATIC_QUAD] = VTK_QUADRATIC_QUAD;
 
  166     vtkmaps [N8_TO_VTK_QUADRATIC_QUAD] = {0, 2, 7, 5, 1, 4, 6, 3};
 
  167     vtktypes[N10_TO_VTK_QUADRATIC_TETRA] = VTK_QUADRATIC_TETRA;
 
  168     vtkmaps [N10_TO_VTK_QUADRATIC_TETRA] = {0, 2, 5, 9, 1, 4, 3, 6, 7, 8};
 
  169     vtktypes[N20_TO_VTK_QUADRATIC_HEXAHEDRON] = VTK_QUADRATIC_HEXAHEDRON;
 
  170     vtkmaps [N20_TO_VTK_QUADRATIC_HEXAHEDRON] = {0, 2, 7, 5, 12, 14, 19, 17, 1, 4, 6, 3, 13, 16, 18, 15, 8, 9, 11, 10};
 
  171     vtktypes[N15_TO_VTK_QUADRATIC_WEDGE] = VTK_QUADRATIC_WEDGE;
 
  172     vtkmaps [N15_TO_VTK_QUADRATIC_WEDGE] = {0, 2, 5, 9, 11, 14, 1, 4, 3, 10, 13, 12, 6, 7, 8};
 
  174     vtktypes[N13_TO_VTK_QUADRATIC_PYRAMID] = VTK_QUADRATIC_PYRAMID;
 
  175     vtkmaps [N13_TO_VTK_QUADRATIC_PYRAMID] = {0, 2, 7, 5, 12, 1, 4, 6, 3, 8, 9, 11, 10};
 
  176     vtktypes[N14_TO_VTK_QUADRATIC_PYRAMID] = VTK_QUADRATIC_PYRAMID;
 
  177     vtkmaps [N14_TO_VTK_QUADRATIC_PYRAMID] = {0, 2, 8, 6, 13, 1, 5, 7, 3, 9, 10, 12, 11};
 
  178     vtktypes[N9_TO_VTK_BIQUADRATIC_QUAD] = VTK_BIQUADRATIC_QUAD;
 
  179     vtkmaps [N9_TO_VTK_BIQUADRATIC_QUAD] = {0, 2, 8, 6, 1, 5, 7, 3, 4};
 
  180     vtktypes[N27_TO_VTK_TRIQUADRATIC_HEXAHEDRON] = VTK_TRIQUADRATIC_HEXAHEDRON;
 
  181     vtkmaps [N27_TO_VTK_TRIQUADRATIC_HEXAHEDRON] = {0, 2, 8, 6, 18, 20, 26, 24, 1, 5, 7, 3, 19, 23, 25, 21, 9, 11, 17, 15, 12, 14, 10, 16, 4, 22};
 
  182     vtktypes[N18_TO_VTK_BIQUADRATIC_QUADRATIC_WEDGE] = VTK_BIQUADRATIC_QUADRATIC_WEDGE;
 
  183     vtkmaps [N18_TO_VTK_BIQUADRATIC_QUADRATIC_WEDGE]  = {0, 2, 5, 12, 14, 17, 1, 4, 3, 13, 16, 15, 6, 8, 11, 7, 10, 9};
 
  186   static const std::vector<unsigned> &
 
  187   select_vtk_dof_mapping(
unsigned t) {
 
  189     if (vtkmaps.size() == 0) init_gf2vtk();
 
  193   int select_vtk_type(
unsigned t) {
 
  195     if (vtktypes.size() == 0) init_gf2vtk();
 
  200   vtk_export::vtk_export(std::ostream &os_, 
bool ascii_, 
bool vtk_)
 
  201     : os(os_), ascii(ascii_), vtk(vtk_) { init(); }
 
  203   vtk_export::vtk_export(
const std::string& fname, 
bool ascii_, 
bool vtk_)
 
  204     : os(real_os), ascii(ascii_), vtk(vtk_),
 
  205     real_os(fname.c_str(), !ascii ? std::ios_base::binary | std::ios_base::out
 
  206                                   : std::ios_base::out) {
 
  207     GMM_ASSERT1(real_os, 
"impossible to write to file '" << fname << 
"'");
 
  211   vtk_export::~vtk_export(){
 
  213       if (state == IN_CELL_DATA) os << 
"</CellData>\n";
 
  214       if (state == IN_POINT_DATA) os << 
"</PointData>\n";
 
  216       os << 
"</UnstructuredGrid>\n";
 
  217       os << 
"</VTKFile>\n";
 
  221   void vtk_export::init() {
 
  222     strcpy(header, 
"Exported by GetFEM");
 
  223     psl = 0; dim_ = dim_type(-1);
 
  224     static int test_endian = 0x01234567;
 
  225     reverse_endian = (*((
char*)&test_endian) == 0x67);
 
  230   void vtk_export::switch_to_cell_data() {
 
  231     if (state != IN_CELL_DATA) {
 
  234         if (psl) 
for (
auto i : {0,1,2,3}) nb_cells += psl->nb_simplexes(i);
 
  235         else nb_cells = pmf->convex_index().card();
 
  237         os << 
"CELL_DATA " << nb_cells << 
"\n";
 
  240         if (state == IN_POINT_DATA) os << 
"</PointData>\n";
 
  241         os << 
"<CellData>\n";
 
  243       state = IN_CELL_DATA;
 
  247   void vtk_export::switch_to_point_data() {
 
  248     if (state != IN_POINT_DATA) {
 
  251         os << 
"POINT_DATA " << (psl ? psl->nb_points()
 
  252                                     : pmf_dof_used.card()) << 
"\n";
 
  255         if (state == IN_CELL_DATA) os << 
"</CellData>\n";
 
  256         os << 
"<PointData>\n";
 
  258       state = IN_POINT_DATA;
 
  263   void vtk_export::exporting(
const stored_mesh_slice& sl) {
 
  264     psl = &sl; dim_ = dim_type(sl.dim());
 
  265     GMM_ASSERT1(psl->dim() <= 3, 
"attempt to export a " << 
int(dim_)
 
  266               << 
"D slice (not supported)");
 
  269   void vtk_export::exporting(
const mesh& m) {
 
  271     GMM_ASSERT1(dim_ <= 3, 
"attempt to export a " << 
int(dim_)
 
  272                 << 
"D mesh (not supported)");
 
  273     pmf = std::make_unique<mesh_fem>(
const_cast<mesh&
>(m), dim_type(1));
 
  274     for (dal::bv_visitor cv(m.
convex_index()); !cv.finished(); ++cv) {
 
  277       pmf->set_finite_element(cv, pf);
 
  282   void vtk_export::exporting(
const mesh_fem& mf) {
 
  284     GMM_ASSERT1(dim_ <= 3, 
"attempt to export a " << 
int(dim_)
 
  285                 << 
"D mesh_fem (not supported)");
 
  286     if (&mf != pmf.get())
 
  287       pmf = std::make_unique<mesh_fem>(mf.
linked_mesh());
 
  290     for (dal::bv_visitor cv(mf.
convex_index()); !cv.finished(); ++cv) {
 
  297           pf == 
fem_descriptor(
"FEM_PYRAMID_Q2_INCOMPLETE_DISCONTINUOUS") ||
 
  300         pmf->set_finite_element(cv, pf);
 
  302         bool discontinuous = 
false;
 
  303         for (
unsigned i=0; i < pf->nb_dof(cv); ++i) {
 
  305           if (!
dof_linkable(pf->dof_types()[i])) { discontinuous = 
true; 
break; }
 
  312         if ((pf != classical_pf1 && pf->estimated_degree() > 1) ||
 
  313             pgt->structure() != pgt->basic_structure())
 
  316         pmf->set_finite_element(cv, discontinuous ?
 
  323     const mesh &m = pmf->linked_mesh();
 
  324     pmf_mapping_type.resize(pmf->convex_index().last_true() + 1, 
unsigned(-1));
 
  325     pmf_dof_used.sup(0, pmf->nb_basic_dof());
 
  326     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
  327       vtk_mapping_type t = NO_VTK_MAPPING;
 
  328       size_type nbd = pmf->fem_of_element(cv)->nb_dof(cv);
 
  329       switch (pmf->fem_of_element(cv)->dim()) {
 
  330       case 0: t = N1_TO_VTK_VERTEX; 
break;
 
  332         if (nbd == 2) t = N2_TO_VTK_LINE;
 
  333         else if (nbd == 3) t = N3_TO_VTK_QUADRATIC_EDGE;
 
  336         if (nbd == 3) t = N3_TO_VTK_TRIANGLE;
 
  338           t = check_voxel(m.points_of_convex(cv)) ? N4_TO_VTK_PIXEL
 
  340         else if (nbd == 6) t = N6_TO_VTK_QUADRATIC_TRIANGLE;
 
  341         else if (nbd == 8) t = N8_TO_VTK_QUADRATIC_QUAD;
 
  342         else if (nbd == 9) t = N9_TO_VTK_BIQUADRATIC_QUAD;
 
  345         if (nbd == 4) t = N4_TO_VTK_TETRA;
 
  346         else if (nbd == 10) t = N10_TO_VTK_QUADRATIC_TETRA;
 
  348           t = check_voxel(m.points_of_convex(cv)) ? N8_TO_VTK_VOXEL
 
  349                                                   : N8_TO_VTK_HEXAHEDRON;
 
  350         else if (nbd == 20) t = N20_TO_VTK_QUADRATIC_HEXAHEDRON;
 
  351         else if (nbd == 27) t = N27_TO_VTK_TRIQUADRATIC_HEXAHEDRON;
 
  352         else if (nbd == 5) t = N5_TO_VTK_PYRAMID;
 
  353         else if (nbd == 13) t = N13_TO_VTK_QUADRATIC_PYRAMID;
 
  354         else if (nbd == 14) t = N14_TO_VTK_QUADRATIC_PYRAMID;
 
  355         else if (nbd == 6) t = N6_TO_VTK_WEDGE;
 
  356         else if (nbd == 15) t = N15_TO_VTK_QUADRATIC_WEDGE;
 
  357         else if (nbd == 18) t = N18_TO_VTK_BIQUADRATIC_QUADRATIC_WEDGE;
 
  360       GMM_ASSERT1(t != -1, 
"semi internal error. Could not map " <<
 
  362                 << 
" to a VTK cell type");
 
  363       pmf_mapping_type[cv] = t;
 
  365       const std::vector<unsigned> &dmap = select_vtk_dof_mapping(t);
 
  367       GMM_ASSERT1(dmap.size() <= pmf->nb_basic_dof_of_element(cv),
 
  368                 "inconsistency in vtk_dof_mapping");
 
  369       for (
unsigned i=0; i < dmap.size(); ++i)
 
  370         pmf_dof_used.add(pmf->ind_basic_dof_of_element(cv)[dmap[i]]);
 
  377   const stored_mesh_slice& vtk_export::get_exported_slice()
 const {
 
  378     GMM_ASSERT1(psl, 
"no slice!");
 
  382   const mesh_fem& vtk_export::get_exported_mesh_fem()
 const {
 
  383     GMM_ASSERT1(pmf.get(), 
"no mesh_fem!");
 
  387   void vtk_export::set_header(
const std::string& s)
 
  389     strncpy(header, s.c_str(), 256);
 
  393   void vtk_export::check_header() {
 
  394     if (state >= HEADER_WRITTEN) 
return;
 
  396       os << 
"# vtk DataFile Version 2.0\n";
 
  397       os << header << 
"\n";
 
  398       os << (ascii ? 
"ASCII\n" : 
"BINARY\n");
 
  400       os << 
"<?xml version=\"1.0\"?>\n";
 
  401       os << 
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" ";
 
  402       os << 
"byte_order=\"" << (reverse_endian ? 
"LittleEndian" : 
"BigEndian") << 
"\">\n";
 
  403       os << 
"<!--" << header << 
"-->\n";
 
  404       os << 
"<UnstructuredGrid>\n";
 
  406     state = HEADER_WRITTEN;
 
  409   void vtk_export::write_separ()
 
  410   { 
if (ascii) os << 
"\n"; }
 
  412   void vtk_export::clear_vals()
 
  413   { 
if (!vtk && !ascii) vals.clear(); }
 
  415   void vtk_export::write_vals() {
 
  416     if (!vtk && !ascii) {
 
  417       os << base64_encode(vals);
 
  422   void vtk_export::write_mesh() {
 
  423     if (psl) write_mesh_structure_from_slice();
 
  424     else write_mesh_structure_from_mesh_fem();
 
  428   void vtk_export::write_mesh_structure_from_slice() {
 
  430     static int vtk_simplex_code[4] = { VTK_VERTEX, VTK_LINE, VTK_TRIANGLE, VTK_TETRA };
 
  431     if (state >= STRUCTURE_WRITTEN) 
return;
 
  435     for (
size_type ic=0; ic < psl->nb_convex(); ++ic) {
 
  436       for (
const slice_simplex &s : psl->simplexes(ic))
 
  437        cells_cnt += s.dim() + 2;
 
  438       splx_cnt += psl->simplexes(ic).size();
 
  442       os << 
"DATASET UNSTRUCTURED_GRID\n";
 
  443       os << 
"POINTS " << psl->nb_points() << 
" float\n";
 
  445       os << 
"<Piece NumberOfPoints=\"" << psl->nb_points();
 
  446       os << 
"\" NumberOfCells=\"" << splx_cnt << 
"\">\n";
 
  448       os << 
"<DataArray type=\"Float32\" Name=\"Points\" ";
 
  449       os << 
"NumberOfComponents=\"3\" ";
 
  450       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  451       if (!ascii) write_val(
int(
sizeof(
float)*psl->nb_points()*3));
 
  458     for (
size_type ic=0; ic < psl->nb_convex(); ++ic) {
 
  459       for (
size_type i=0; i < psl->nodes(ic).size(); ++i)
 
  460        write_vec(psl->nodes(ic)[i].pt.begin(),psl->nodes(ic)[i].pt.size());
 
  465       os << (ascii ? 
"" : 
"\n") << 
"</DataArray>\n";
 
  472       write_separ(); os << 
"CELLS " << splx_cnt << 
" " << cells_cnt << 
"\n";
 
  475       os << 
"<DataArray type=\"Int32\" Name=\"connectivity\" ";
 
  476       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  479         for (
size_type ic=0; ic < psl->nb_convex(); ++ic) {
 
  480           for (
const slice_simplex &s : psl->simplexes(ic))
 
  481             size += 
int((s.dim()+1)*
sizeof(int));
 
  486     for (
size_type ic=0; ic < psl->nb_convex(); ++ic) {
 
  487       for (
const slice_simplex &s : psl->simplexes(ic)) {
 
  489           write_val(
int(s.dim()+1));
 
  491           write_val(
int(s.inodes[j] + nodes_cnt));
 
  494       nodes_cnt += psl->nodes(ic).size();
 
  496     assert(nodes_cnt == psl->nb_points()); 
 
  499       write_separ(); os << 
"CELL_TYPES " << splx_cnt << 
"\n";
 
  501       os << (ascii ? 
"" : 
"\n") << 
"</DataArray>\n";
 
  502       os << 
"<DataArray type=\"Int32\" Name=\"offsets\" ";
 
  503       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  506         for (
size_type ic=0; ic < psl->nb_convex(); ++ic)
 
  507           size += 
int(psl->simplexes(ic).size()*
sizeof(int));
 
  512     for (
size_type ic=0; ic < psl->nb_convex(); ++ic) {
 
  513       for (
const slice_simplex &s : psl->simplexes(ic))
 
  515           write_val(
int(vtk_simplex_code[s.dim()]));
 
  517           cnt += int(s.dim()+1);
 
  521       splx_cnt -= psl->simplexes(ic).size();
 
  524     assert(splx_cnt == 0); 
 
  526       os << (ascii ? 
"" : 
"\n") << 
"</DataArray>\n";
 
  527       os << 
"<DataArray type=\"Int32\" Name=\"types\" ";
 
  528       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  531         for (
size_type ic=0; ic < psl->nb_convex(); ++ic)
 
  532           size += 
int(psl->simplexes(ic).size()*
sizeof(int));
 
  535       for (
size_type ic=0; ic < psl->nb_convex(); ++ic)
 
  536         for (
const slice_simplex &s : psl->simplexes(ic))
 
  537           write_val(
int(vtk_simplex_code[s.dim()]));
 
  539       os << 
"\n" << 
"</DataArray>\n";
 
  542     state = STRUCTURE_WRITTEN;
 
  546   void vtk_export::write_mesh_structure_from_mesh_fem() {
 
  547     if (state >= STRUCTURE_WRITTEN) 
return;
 
  551       os << 
"DATASET UNSTRUCTURED_GRID\n";
 
  552       os << 
"POINTS " << pmf_dof_used.card() << 
" float\n";
 
  554       os << 
"<Piece NumberOfPoints=\"" << pmf_dof_used.card()
 
  555          << 
"\" NumberOfCells=\"" << pmf->convex_index().card() << 
"\">\n";
 
  557       os << 
"<DataArray type=\"Float32\" Name=\"Points\" ";
 
  558       os << 
"NumberOfComponents=\"3\" ";
 
  559       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  560       if (!ascii) write_val(
int(
sizeof(
float)*pmf_dof_used.card()*3));
 
  562     std::vector<int> dofmap(pmf->nb_dof());
 
  564     for (dal::bv_visitor d(pmf_dof_used); !d.finished(); ++d) {
 
  566       base_node P = pmf->point_of_basic_dof(d);
 
  567       write_vec(P.const_begin(),P.size());
 
  573     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv)
 
  574       nb_cell_values += (1 + select_vtk_dof_mapping(pmf_mapping_type[cv]).size());
 
  578       os << 
"CELLS " << pmf->convex_index().card() << 
" " << nb_cell_values << 
"\n";
 
  580       os << (ascii ? 
"" : 
"\n") << 
"</DataArray>\n";
 
  583       os << 
"<DataArray type=\"Int32\" Name=\"connectivity\" ";
 
  584       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  587         for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
  588           const std::vector<unsigned> &dmap = select_vtk_dof_mapping(pmf_mapping_type[cv]);
 
  589           size += int(
sizeof(
int)*dmap.size());
 
  595     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
  596       const std::vector<unsigned> &dmap = select_vtk_dof_mapping(pmf_mapping_type[cv]);
 
  597       if (vtk) write_val(
int(dmap.size()));
 
  598       for (
size_type i=0; i < dmap.size(); ++i)
 
  599         write_val(
int(dofmap[pmf->ind_basic_dof_of_element(cv)[dmap[i]]]));
 
  606       os << 
"CELL_TYPES " << pmf->convex_index().card() << 
"\n";
 
  608       os << (ascii ? 
"" : 
"\n") << 
"</DataArray>\n";
 
  609       os << 
"<DataArray type=\"Int32\" Name=\"offsets\" ";
 
  610       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  612         write_val(
int(pmf->convex_index().card()*
sizeof(
int)));
 
  614       for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
  615         const std::vector<unsigned> &dmap = select_vtk_dof_mapping(pmf_mapping_type[cv]);
 
  616         cnt += int(dmap.size());
 
  620       os << 
"\n" << 
"</DataArray>\n";
 
  621       os << 
"<DataArray type=\"Int32\" Name=\"types\" ";
 
  622       os << (ascii ? 
"format=\"ascii\">\n" : 
"format=\"binary\">\n");
 
  624         write_val(
int(pmf->convex_index().card()*
sizeof(
int)));
 
  626     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
  627       write_val(
int(select_vtk_type(pmf_mapping_type[cv])));
 
  628       if (vtk) write_separ();
 
  631     if (!vtk) os << 
"\n" << 
"</DataArray>\n" << 
"</Cells>\n";
 
  633     state = STRUCTURE_WRITTEN;
 
  636   void vtk_export::write_mesh_quality(
const mesh &m) {
 
  640       std::vector<scalar_type> q(mf.
nb_dof());
 
  644       write_point_data(mf, q, 
"convex_quality");
 
  646       std::vector<scalar_type> q(pmf->convex_index().card());
 
  647       for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
  650       write_cell_data(q, 
"convex_quality");
 
  659   dx_export::dx_export(std::ostream &os_, 
bool ascii_)
 
  660     : os(os_), ascii(ascii_) { init(); }
 
  662   dx_export::dx_export(
const std::string& fname, 
bool ascii_, 
bool append_)
 
  663     : os(real_os), ascii(ascii_) {
 
  664     real_os.open(fname.c_str(),
 
  665                  std::ios_base::openmode(std::ios_base::in |
 
  667                   (append_ ? std::ios_base::ate : std::ios_base::trunc)));
 
  668     GMM_ASSERT1(real_os.good(), 
"impossible to write to dx file '" 
  671     if (append_) { reread_metadata(); header_written = 
true; }
 
  674   dx_export::~dx_export() {
 
  675     std::ios::pos_type p = os.tellp();
 
  677     os << 
"\n# --end of getfem export\nend\n";
 
  681   void dx_export::init() {
 
  682     strcpy(header, 
"Exported by GetFEM");
 
  683     psl = 0; dim_ = dim_type(-1); connections_dim = dim_type(-1);
 
  684     psl_use_merged = 
false;
 
  685     header_written = 
false;
 
  688   void dx_export::write_separ()
 
  689   { 
if (ascii) os << 
"\n"; }
 
  691   template<
typename T> 
static typename std::list<T>::iterator
 
  692   get_from_name(std::list<T> &c,
 
  693               const std::string& name, 
bool raise_error) {
 
  694     for (
typename std::list<T>::iterator it = c.begin();
 
  695         it != c.end(); ++it) {
 
  696       if (it->name == name) 
return it;
 
  698     GMM_ASSERT1(!raise_error, 
"object not found in dx file: " << name);
 
  702   std::list<dx_export::dxMesh>::iterator
 
  703   dx_export::get_mesh(
const std::string& name, 
bool raise_error) {
 
  704     return get_from_name(meshes,name,raise_error);
 
  706   std::list<dx_export::dxObject>::iterator
 
  707   dx_export::get_object(
const std::string& name, 
bool raise_error) {
 
  708     return get_from_name(objects,name,raise_error);
 
  712   bool dx_export::new_mesh(std::string &name) {
 
  713     name = default_name(name, 
int(meshes.size()), 
"mesh");
 
  714     std::list<dxMesh>::iterator it = get_mesh(name, 
false);
 
  715     if (it != meshes.end()) {
 
  716       if (&(*it) != ¤t_mesh())
 
  717        std::swap(current_mesh(),*it);
 
  720       meshes.push_back(dxMesh()); meshes.back().name = name;
 
  725   void dx_export::exporting(
const stored_mesh_slice& sl, 
bool merge_points,
 
  727     if (!new_mesh(name)) 
return;
 
  728     psl_use_merged = merge_points;
 
  729     if (merge_points) sl.merge_nodes();
 
  730     psl = &sl; dim_ = dim_type(sl.dim());
 
  731     GMM_ASSERT1(psl->
dim() <= 3, 
"4D slices and more are not supported");
 
  732     for (dim_type d = 0; d <= psl->
dim(); ++d) {
 
  734         if (connections_dim == dim_type(-1)) connections_dim = d;
 
  735         else GMM_ASSERT1(
false, 
"Cannot export a slice containing " 
  736                       "simplexes of different dimensions");
 
  739     GMM_ASSERT1(connections_dim != dim_type(-1), 
"empty slice!");
 
  743   void dx_export::exporting(
const mesh_fem& mf, std::string name) {
 
  744     name = default_name(name, 
int(meshes.size()), 
"mesh");
 
  745     if (!new_mesh(name)) 
return;
 
  746     const mesh &m = mf.linked_mesh();
 
  747     GMM_ASSERT1(mf.linked_mesh().convex_index().card() != 0,
 
  748               "won't export an empty mesh");
 
  751     GMM_ASSERT1(dim_ <= 3, 
"4D meshes and more are not supported");
 
  752     if (&mf != pmf.get())
 
  753       pmf = std::make_unique<mesh_fem>(
const_cast<mesh&
>(m), dim_type(1));
 
  755     GMM_ASSERT1(dxname_of_convex_structure
 
  757               "DX Cannot handle " <<
 
  760     for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
 
  764                   "Cannot export this mesh to opendx, it contains " 
  765                   "different convex types. Slice it first.");
 
  766       pfem pf = mf.fem_of_element(cv);
 
  767       bool discontinuous = 
false;
 
  768       for (
unsigned i=0; i < pf->nb_dof(cv); ++i) {
 
  770         if (!
dof_linkable(pf->dof_types()[i])) { discontinuous = 
true; 
break; }
 
  774       pmf->set_finite_element(cv, classical_pf1);
 
  776     pmf_dof_used.add(0, pmf->nb_basic_dof());
 
  777     connections_dim = dim_type(pmf->nb_basic_dof_of_element(m.convex_index().first_true()));
 
  780   void dx_export::exporting(
const mesh& m, std::string name) {
 
  782     GMM_ASSERT1(dim_ <= 3, 
"4D meshes and more are not supported");
 
  783     pmf = std::make_unique<mesh_fem>(
const_cast<mesh&
>(m), dim_type(1));
 
  784     pmf->set_classical_finite_element(1);
 
  785     exporting(*pmf, name);
 
  788   void dx_export::write_series() {
 
  789     for (std::list<dxSeries>::const_iterator it = series.begin();
 
  790         it != series.end(); ++it) {
 
  791       if (it->members.size() == 0) 
continue;
 
  793       os << 
"\nobject  \"" << it->name << 
"\" class series\n";
 
  794       for (std::list<std::string>::const_iterator ito = it->members.begin();
 
  795           ito != it->members.end(); ++ito, ++count) {
 
  796        os << 
"  member  " << count << 
" \"" << (*ito) << 
"\"\n";
 
  801   void dx_export::serie_add_object_(
const std::string &serie_name,
 
  802                                const std::string &object_name) {
 
  803     std::list<dxSeries>::iterator it = series.begin();
 
  804     while (it != series.end() && it->name != serie_name) ++it;
 
  805     if (it == series.end()) {
 
  806       series.push_back(dxSeries()); it = series.end(); --it;
 
  807       it->name = serie_name;
 
  809     it->members.push_back(object_name);
 
  813                                const std::string &object_name) {
 
  816     std::list<dxObject>::iterator ito = get_object(object_name, 
false);
 
  817     if (ito != objects.end()) {
 
  818       std::list<dxMesh>::iterator itm = get_mesh(ito->mesh);
 
  819       if (itm != meshes.end() && (itm->flags & dxMesh::WITH_EDGES)) {
 
  820        serie_add_object_(serie_name + 
"_edges",
 
  821                       object_name + 
"_edges");
 
  825     serie_add_object_(serie_name, object_name);
 
  829   { strncpy(header, s.c_str(), 256); header[255] = 0; }
 
  831   void dx_export::check_header() {
 
  832     if (header_written) 
return;
 
  833     header_written = 
true;
 
  834     os << 
"# data file for IBM OpenDX, generated by GetFem++ v " 
  835        << GETFEM_VERSION << 
"\n";
 
  836     os << 
"# " << header << 
"\n";
 
  839   void dx_export::update_metadata(std::ios::pos_type pos_series) {
 
  840     os.seekp(0,std::ios::end);
 
  841     os << 
"# This file contains the following objects\n";
 
  842     std::ios::pos_type pos_end = os.tellp();
 
  843     for (std::list<dxSeries>::const_iterator it = series.begin();
 
  844         it != series.end(); ++it) {
 
  845       os << 
"#S \"" << it->name << 
"\" which contains:\n";
 
  846       for (std::list<std::string>::const_iterator its = it->members.begin();
 
  847            its != it->members.end(); ++its)
 
  848         os << 
"#+   \"" << *its << 
"\"\n";
 
  850     for (std::list<dxObject>::const_iterator it = objects.begin();
 
  851         it != objects.end(); ++it) {
 
  852       os << 
"#O \"" << it->name << 
"\" \"" << it->mesh << 
"\"\n";
 
  854     for (std::list<dxMesh>::const_iterator it = meshes.begin();
 
  855         it != meshes.end(); ++it) {
 
  856       os << 
"#M \"" << it->name << 
"\" " << it->flags << 
"\n";
 
  858     os << 
"#E \"THE_END\" " << std::setw(20) << pos_series << std::setw(20) << pos_end << 
"\n";
 
  861   void dx_export::reread_metadata() {
 
  863     real_os.seekg(0, std::ios::end);
 
  865     unsigned long lu_end, lu_series;
 
  867       real_os.seekg(-1, std::ios::cur);
 
  868       c = char(real_os.peek());
 
  869     } 
while (++count < 512 && c != 
'#');
 
  870     real_os.getline(line, 
sizeof line);
 
  871     if (sscanf(line, 
"#E \"THE_END\" %lu %lu", &lu_series, &lu_end) != 2)
 
  872       GMM_ASSERT1(
false, 
"this file was not generated by getfem, " 
  873                 "cannot append data to it!\n");
 
  874     real_os.seekg(lu_end, std::ios::beg);
 
  876       char name[512]; 
unsigned n;
 
  878       real_os.getline(line, 
sizeof line);
 
  879       if (sscanf(line, 
"#%c \"%512[^\"]\"%n", &c, name, &pos) < 1)
 
  880         GMM_ASSERT1(
false, 
"corrupted file! your .dx file is broken\n");
 
  882         series.push_back(dxSeries()); series.back().name = name;
 
  883       } 
else if (c == 
'+') {
 
  884         series.back().members.push_back(name);
 
  885       } 
else if (c == 
'O') {
 
  886         objects.push_back(dxObject()); objects.back().name = name;
 
  887         sscanf(line+pos, 
" \"%512[^\"]\"", name); objects.back().mesh = name;
 
  888       } 
else if (c == 
'M') {
 
  889         meshes.push_back(dxMesh()); meshes.back().name = name;
 
  890         sscanf(line+pos, 
"%u", &n); meshes.back().flags = n;
 
  891       } 
else if (c == 
'E') {
 
  893       } 
else GMM_ASSERT1(
false, 
"corrupted file! your .dx file is broken\n");
 
  895     real_os.seekp(lu_series, std::ios::beg);
 
  899     const char *s_elem_type = dxname_of_convex_structure(cvs);
 
  901       GMM_WARNING1(
"OpenDX won't handle this kind of convexes");
 
  902     os << 
"\n  attribute \"element type\" string \"" << s_elem_type << 
"\"\n" 
  903        << 
"  attribute \"ref\" string \"positions\"\n\n";
 
  907     const char *s_elem_type = 0;
 
  908     switch (cvs->dim()) {
 
  910       case 1: s_elem_type = 
"lines"; 
break;
 
  912        if (cvs->nb_points() == 3)
 
  913          s_elem_type = 
"triangles";
 
  914        else if (cvs->nb_points() == 4)
 
  915          s_elem_type = 
"quads";
 
  918        if (cvs->nb_points() == 4)
 
  919          s_elem_type = 
"tetrahedra";
 
  920        else if (cvs->nb_points() == 8)
 
  921          s_elem_type = 
"cubes";
 
  927   void dx_export::write_mesh() {
 
  929     if (current_mesh().flags & dxMesh::STRUCTURE_WRITTEN) 
return;
 
  930     if (psl) write_mesh_structure_from_slice();
 
  931     else write_mesh_structure_from_mesh_fem();
 
  934        << 
"  component \"positions\" value \"" 
  936        << 
"  component \"connections\" value \"" 
  938     current_mesh().flags |= dxMesh::STRUCTURE_WRITTEN;
 
  942   void dx_export::write_mesh_structure_from_slice() {
 
  944        << 
"\" class array type float rank 1 shape " 
  947     if (!ascii) os << 
" " << endianness() << 
" binary";
 
  948     os << 
" data follows\n";
 
  949     if (psl_use_merged) {
 
  959            write_val(
float(psl->
nodes(ic)[i].pt[k]));
 
  965        << 
"\" class array type int rank 1 shape " 
  966        << int(connections_dim+1)
 
  968     if (!ascii) os << 
" " << endianness() << 
" binary";
 
  969     os << 
" data follows\n";
 
  973       for (
const slice_simplex &s : psl->
simplexes(ic)) {
 
  974         if (s.dim() == connections_dim) {
 
  975           for (
size_type j=0; j < s.dim()+1; ++j) {
 
  978               k = psl->merged_index(ic, s.inodes[j]);
 
  979             else k = psl->global_index(ic, s.inodes[j]);
 
  985       nodes_cnt += psl->
nodes(ic).size();
 
  992   void dx_export::write_mesh_structure_from_mesh_fem() {
 
  994        << 
"\" class array type float rank 1 shape " 
  995        << int(pmf->linked_mesh().dim())
 
  996        << 
" items " << pmf->nb_dof();
 
  997     if (!ascii) os << 
" " << endianness() << 
" binary";
 
  998     os << 
" data follows\n";
 
 1001     for (
size_type d = 0; d < pmf->nb_basic_dof(); ++d) {
 
 1002       const base_node P = pmf->point_of_basic_dof(d);
 
 1004        write_val(
float(P[k]));
 
 1009        << 
"\" class array type int rank 1 shape " 
 1010        << int(connections_dim)
 
 1011        << 
" items " << pmf->convex_index().card();
 
 1012     if (!ascii) os << 
" " << endianness() << 
" binary";
 
 1013     os << 
" data follows\n";
 
 1015     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
 1016       for (
size_type i=0; i < connections_dim; ++i)
 
 1017         write_val(
int(pmf->ind_basic_dof_of_element(cv)[i]));
 
 1020     write_convex_attributes(
basic_structure(pmf->linked_mesh().structure_of_convex(pmf->convex_index().first_true())));
 
 1025     if (current_mesh().flags & dxMesh::WITH_EDGES) 
return;
 
 1026     if (psl) write_mesh_edges_from_slice(with_slice_edges);
 
 1027     else write_mesh_edges_from_mesh();
 
 1028     current_mesh().flags |= dxMesh::WITH_EDGES;
 
 1030        << 
"\" class field\n" 
 1031        << 
"  component \"positions\" value \"" 
 1033        << 
"  component \"connections\" value \"" 
 1038   void dx_export::write_mesh_edges_from_slice(
bool with_slice_edges) {
 
 1039     std::vector<size_type> edges;
 
 1040     dal::bit_vector slice_edges;
 
 1041     psl->
get_edges(edges, slice_edges, psl_use_merged);
 
 1042     if (with_slice_edges) slice_edges.clear();
 
 1045        << 
"\" class array type int rank 1 shape 2" 
 1046        << 
" items " << edges.size()/2 - slice_edges.card();
 
 1047     if (!ascii) os << 
" " << endianness() << 
" binary";
 
 1048     os << 
" data follows\n";
 
 1049     for (
size_type i=0; i < edges.size()/2; ++i) {
 
 1050       if (!slice_edges.is_in(i)) {
 
 1051        write_val(
int(edges[2*i]));
 
 1052        write_val(
int(edges[2*i+1]));
 
 1054       if ((i+1)%10 == 0) write_separ();
 
 1060   void dx_export::write_mesh_edges_from_mesh() {
 
 1064        << 
"\" class array type int rank 1 shape 2" 
 1065        << 
" items " << ms.convex_index().card();
 
 1066     if (!ascii) os << 
" " << endianness() << 
" binary";
 
 1067     os << 
" data follows\n";
 
 1068     for (dal::bv_visitor cv(ms.convex_index()); !cv.finished(); ++cv) {
 
 1069       write_val(
int(ms.ind_points_of_convex(cv)[0]));
 
 1070       write_val(
int(ms.ind_points_of_convex(cv)[1]));
 
 1071       if ((cv+1)%20 == 0) write_separ();
 
 1081   struct gf2pos_dof_mapping : 
public std::vector<std::vector<unsigned> > {};
 
 1083   static const std::vector<unsigned>& getfem_to_pos_dof_mapping(
int t) {
 
 1085     if (dm.size() == 0) {
 
 1087       dm[pos_export::POS_PT] = {0};
 
 1088       dm[pos_export::POS_LN] = {0, 1};
 
 1089       dm[pos_export::POS_TR] = {0, 1, 2};
 
 1090       dm[pos_export::POS_QU] = {0, 1, 3, 2};
 
 1091       dm[pos_export::POS_SI] = {0, 1, 2, 3};
 
 1092       dm[pos_export::POS_HE] = {0, 1, 3, 2, 4, 5, 7, 6};
 
 1093       dm[pos_export::POS_PR] = {0, 1, 2, 3, 4, 5};
 
 1094       dm[pos_export::POS_PY] = {0, 1, 3, 2, 4};
 
 1099   pos_export::pos_export(std::ostream& osname): os(osname) {
 
 1103   pos_export::pos_export(
const std::string& fname)
 
 1104     : os(real_os), real_os(fname.c_str()) {
 
 1105     GMM_ASSERT1(real_os, 
"impossible to write to pos file '" << fname << 
"'");
 
 1109   void pos_export::init() {
 
 1110     strcpy(header, 
"Exported by GetFEM");
 
 1115   void pos_export::set_header(
const std::string& s){
 
 1116     strncpy(header, s.c_str(), 256);
 
 1120   void pos_export::check_header() {
 
 1121     if (state >= HEADER_WRITTEN) 
return;
 
 1122     os << 
"/* " << header << 
" */\n";
 
 1123     os << 
"General.FastRedraw = 0;\n";
 
 1124     os << 
"General.ColorScheme = 1;\n";
 
 1125     state = HEADER_WRITTEN;
 
 1128   void pos_export::exporting(
const mesh& m) {
 
 1129     if (state >= STRUCTURE_WRITTEN) 
return;
 
 1130     dim = dim_type(m.dim());
 
 1131     GMM_ASSERT1(
int(dim) <= 3, 
"attempt to export a " 
 1132                 << 
int(dim) << 
"D mesh (not supported)");
 
 1133     pmf = std::make_unique<mesh_fem>(
const_cast<mesh&
>(m), dim_type(1));
 
 1134     pmf->set_classical_finite_element(1);
 
 1136     state = STRUCTURE_WRITTEN;
 
 1139   void pos_export::exporting(
const mesh_fem& mf) {
 
 1140     if (state >= STRUCTURE_WRITTEN) 
return;
 
 1141     dim = dim_type(mf.linked_mesh().dim());
 
 1142     GMM_ASSERT1(
int(dim) <= 3, 
"attempt to export a " 
 1143                 << 
int(dim) << 
"D mesh_fem (not supported)");
 
 1144     if (&mf != pmf.get())
 
 1145       pmf = std::make_unique<mesh_fem>(mf.linked_mesh(), dim_type(1));
 
 1148     for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
 
 1150       pfem pf = mf.fem_of_element(cv);
 
 1152       bool discontinuous = 
false;
 
 1153       for (
unsigned i=0; i < pf->nb_dof(cv); ++i) {
 
 1155         if (!
dof_linkable(pf->dof_types()[i])) { discontinuous = 
true; 
break; }
 
 1157       pfem classical_pf1 = discontinuous ?
 
 1159       pmf->set_finite_element(cv, classical_pf1);
 
 1164     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
 
 1166       switch (pmf->fem_of_element(cv)->nb_dof(cv)){
 
 1167         case 1: t = POS_PT; 
break;
 
 1168         case 2: t = POS_LN; 
break;
 
 1169         case 3: t = POS_TR; 
break;
 
 1171           if ( 2 == pmf->fem_of_element(cv)->dim() ) t = POS_QU;
 
 1172           else if (3 == pmf->fem_of_element(cv)->dim()) t = POS_SI;
 
 1174         case 6: t = POS_PR; 
break;
 
 1175         case 8: t = POS_HE; 
break;
 
 1176         case 5: t = POS_PY; 
break;
 
 1178       GMM_ASSERT1(t != -1, 
"semi internal error. Could not map " 
 1180                            << 
" to a POS primitive type");
 
 1181       pos_cell_type.push_back(
unsigned(t));
 
 1183       const std::vector<unsigned>& dmap = getfem_to_pos_dof_mapping(t);
 
 1184       GMM_ASSERT1(dmap.size() <= pmf->nb_basic_dof_of_element(cv),
 
 1185                   "inconsistency in pos_dof_mapping");
 
 1186       std::vector<unsigned> cell_dof;
 
 1187       cell_dof.resize(dmap.size(),
unsigned(-1));
 
 1188       for (
size_type i=0; i < dmap.size(); ++i)
 
 1189         cell_dof[i] = 
unsigned(pmf->ind_basic_dof_of_element(cv)[dmap[i]]);
 
 1190       pos_cell_dof.push_back(cell_dof);
 
 1192     for (
size_type i=0; i< pmf->nb_basic_dof(); ++i){
 
 1193       std::vector<float> pt;
 
 1194       pt.resize(dim,
float(0));
 
 1196         pt[j] = 
float(pmf->point_of_basic_dof(i)[j]);
 
 1197       pos_pts.push_back(pt);
 
 1199     state = STRUCTURE_WRITTEN;
 
 1202   void pos_export::exporting(
const stored_mesh_slice& sl) {
 
 1203     if (state >= STRUCTURE_WRITTEN) 
return;
 
 1205     dim = dim_type(sl.dim());
 
 1206     GMM_ASSERT1(
int(dim) <= 3, 
"attempt to export a " 
 1207                 << 
int(dim) << 
"D slice (not supported)");
 
 1210       for (
const slice_simplex &s : psl->
simplexes(ic)) {
 
 1213           case 0: t = POS_PT; 
break;
 
 1214           case 1: t = POS_LN; 
break;
 
 1215           case 2: t = POS_TR; 
break;
 
 1216           case 3: t = POS_SI; 
break;
 
 1218         GMM_ASSERT1(t != -1, 
"semi internal error.. could not map to a POS primitive type");
 
 1219         pos_cell_type.push_back(
unsigned(t));
 
 1221         const std::vector<unsigned>& dmap = getfem_to_pos_dof_mapping(t);
 
 1222         GMM_ASSERT1(dmap.size() <= 
size_type(t+1), 
"inconsistency in pos_dof_mapping");
 
 1224         std::vector<unsigned> cell_dof;
 
 1225         cell_dof.resize(dmap.size(),
unsigned(-1));
 
 1226         for (
size_type i=0; i < dmap.size(); ++i)
 
 1227           cell_dof[i] = 
unsigned(s.inodes[dmap[i]] + pcnt);
 
 1228         pos_cell_dof.push_back(cell_dof);
 
 1230       for (
const slice_node &n : psl->
nodes(ic)) {
 
 1231         std::vector<float> pt;
 
 1232         pt.resize(dim,
float(0));
 
 1234           pt[i] = 
float(n.pt[i]);
 
 1235         pos_pts.push_back(pt);
 
 1237       pcnt += psl->
nodes(ic).size();
 
 1239     state = STRUCTURE_WRITTEN;
 
 1242   void pos_export::write(
const mesh& m, 
const std::string &name){
 
 1243     if (state >= IN_CELL_DATA) 
return;
 
 1244     GMM_ASSERT1(
int(m.dim()) <= 3, 
"attempt to export a " 
 1245                 << 
int(m.dim()) << 
"D mesh (not supported)");
 
 1246     pmf = std::make_unique<mesh_fem>(
const_cast<mesh&
>(m), dim_type(1));
 
 1247     pmf->set_classical_finite_element(1);
 
 1249     state = IN_CELL_DATA;
 
 1252   void pos_export::write(
const mesh_fem& mf, 
const std::string &name){
 
 1253     if (state >= IN_CELL_DATA) 
return;
 
 1257     if (
""==name) os << 
"View \"mesh " << view <<
"\" {\n";
 
 1258     else os << 
"View \"" << name <<
"\" {\n";
 
 1261     std::vector<unsigned> cell_dof;
 
 1262     std::vector<float> cell_dof_val;
 
 1263     for (
size_type cell = 0; cell < pos_cell_type.size(); ++cell) {
 
 1264       t = pos_cell_type[cell];
 
 1265       cell_dof = pos_cell_dof[cell];
 
 1266       cell_dof_val.resize(cell_dof.size(),
float(0));
 
 1267       write_cell(t,cell_dof,cell_dof_val);
 
 1271     os << 
"View[" << view << 
"].ShowScale = 0;\n";
 
 1272     os << 
"View[" << view << 
"].ShowElement = 1;\n";
 
 1273     os << 
"View[" << view << 
"].DrawScalars = 0;\n";
 
 1274     os << 
"View[" << view << 
"].DrawVectors = 0;\n";
 
 1275     os << 
"View[" << view++ << 
"].DrawTensors = 0;\n";
 
 1276     state = IN_CELL_DATA;
 
 1279   void pos_export::write(
const stored_mesh_slice& sl, 
const std::string &name){
 
 1280     if (state >= IN_CELL_DATA) 
return;
 
 1284     if (
""==name) os << 
"View \"mesh " << view <<
"\" {\n";
 
 1285     else os << 
"View \"" << name <<
"\" {\n";
 
 1288     std::vector<unsigned> cell_dof;
 
 1289     std::vector<float> cell_dof_val;
 
 1290     for (
size_type cell = 0; cell < pos_cell_type.size(); ++cell) {
 
 1291       t = pos_cell_type[cell];
 
 1292       cell_dof = pos_cell_dof[cell];
 
 1293       cell_dof_val.resize(cell_dof.size(),
float(0));
 
 1294       write_cell(t,cell_dof,cell_dof_val);
 
 1298     os << 
"View[" << view << 
"].ShowScale = 0;\n";
 
 1299     os << 
"View[" << view << 
"].ShowElement = 1;\n";
 
 1300     os << 
"View[" << view << 
"].DrawScalars = 0;\n";
 
 1301     os << 
"View[" << view << 
"].DrawVectors = 0;\n";
 
 1302     os << 
"View[" << view++ << 
"].DrawTensors = 0;\n";
 
 1303     state = IN_CELL_DATA;
 
convenient initialization of vectors via overload of "operator,".
 
Mesh structure definition.
 
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
 
static T & instance()
Instance from the current thread.
 
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.
 
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 size_type first_convex_of_basic_dof(size_type d) const
Shortcut for convex_to_dof(d)[0].
 
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
 
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
 
void set_classical_finite_element(size_type cv, dim_type fem_degree, bool complete=false)
Set a classical (i.e.
 
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash!...
 
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
 
Describe a mesh (collection of convexes (elements) and points).
 
scalar_type convex_quality_estimate(size_type ic) const
Return an estimate of the convex quality (0 <= Q <= 1).
 
size_type dim() const
return the slice dimension
 
void nb_simplexes(std::vector< size_type > &c) const
return the simplex count, in an array.
 
const base_node merged_point(size_type i_merged) const
Return the physical position of the merged node.
 
const mesh_slicer::cs_nodes_ct & nodes(size_type ic) const
Return the list of nodes for the 'ic'th convex of the slice.
 
const mesh_slicer::cs_simplexes_ct & simplexes(size_type ic) const
Return the list of simplexes for the 'ic'th convex of the slice.
 
size_type nb_points() const
Return the number of nodes in the slice.
 
size_type nb_convex() const
return the number of convexes of the original mesh referenced in the slice
 
void get_edges(std::vector< size_type > &edges, dal::bit_vector &slice_edges, bool from_merged_nodes) const
Extract the list of mesh edges.
 
size_type nb_merged_nodes() const
Return the number of merged nodes in slice.
 
A simple singleton implementation.
 
Export solutions to various formats.
 
bool dof_linkable(pdof_description)
Says if the dof is linkable.
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
 
pfem classical_discontinuous_fem(bgeot::pgeometric_trans pg, short_type k, scalar_type alpha=0, bool complete=false)
Give a pointer on the structures describing the classical polynomial discontinuous fem of degree k on...
 
pfem classical_fem(bgeot::pgeometric_trans pgt, short_type k, bool complete=false)
Give a pointer on the structures describing the classical polynomial fem of degree k on a given conve...
 
std::string name_of_fem(pfem p)
get the string name of a fem descriptor.
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
std::string name_of_geometric_trans(pgeometric_trans p)
Get the string name of a geometric transformation.
 
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
 
pconvex_structure simplex_structure(dim_type nc)
Give a pointer on the structures of a simplex of dimension d.
 
size_t size_type
used as the common size type in the library
 
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
GEneric Tool for Finite Element Methods.