getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] (no subject)


From: Tetsuo Koyama
Subject: [Getfem-commits] (no subject)
Date: Sat, 3 Oct 2020 21:43:31 -0400 (EDT)

branch: devel-tetsuo-xml-binary-squash
commit 732533f63e119c7f96e3d54a3e8e032b1356f933
Author: Tetsuo Koyama <tkoyama010@gmail.com>
AuthorDate: Sun Oct 4 09:37:05 2020 +0900

    Add VTU(XML) binary option
---
 .travis.yml                                |   1 +
 interface/src/gf_mesh_fem_get.cc           |  33 +++++++
 interface/src/gf_mesh_get.cc               |  25 ++++++
 interface/src/gf_slice_get.cc              |  72 +++++++++++++++
 interface/tests/python/Makefile.am         |   2 +
 interface/tests/python/check_export_vtu.py |  60 +++++++++++++
 requirements.txt                           |   1 +
 src/getfem/getfem_export.h                 |  51 ++++++-----
 src/getfem_export.cc                       | 139 ++++++++++++++++++++++-------
 9 files changed, 331 insertions(+), 53 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index f8a6b9b..7b7d300 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,6 +24,7 @@ before_install:
 - sudo apt-get install -y --no-install-recommends xzdec
 - sudo apt-get install -y --no-install-recommends fig2ps
 - sudo apt-get install -y --no-install-recommends gv
+- sudo apt-get install -y --no-install-recommends python3-vtk7
 - pip install -r requirements.txt
 addons:
   apt:
diff --git a/interface/src/gf_mesh_fem_get.cc b/interface/src/gf_mesh_fem_get.cc
index 03abb0c..8a179b1 100644
--- a/interface/src/gf_mesh_fem_get.cc
+++ b/interface/src/gf_mesh_fem_get.cc
@@ -763,6 +763,39 @@ void gf_mesh_fem_get(getfemint::mexargs_in& m_in,
        }
        );
 
+    /*@GET ('export to vtu',@str filename, ... ['ascii'], U, 'name'...)
+    Export a @tmf and some fields to a vtu file.
+
+    The FEM and geometric transformations will be mapped to order 1
+    or 2 isoparametric Pk (or Qk) FEMs (as VTK(XML) does not handle higher
+    order elements). If you need to represent high-order FEMs or
+    high-order geometric transformations, you should consider
+    SLICE:GET('export to vtu').@*/
+    sub_command
+      ("export to vtu", 0, -1, 0, 0,
+       std::string fname = in.pop().to_string();
+       bool ascii = false;
+       while (in.remaining() && in.front().is_string()) {
+        std::string cmd2 = in.pop().to_string();
+        if (cmd_strmatch(cmd2, "ascii"))
+          ascii = true;
+        else THROW_BADARG("expecting 'ascii', got " << cmd2);
+       }
+       getfem::vtu_export exp(fname, ascii);
+       exp.exporting(*mf);
+       exp.write_mesh();
+       int count = 1;
+       while (in.remaining()) {
+        const getfem::mesh_fem *mf2 = mf;
+        if (in.remaining() >= 2 && is_meshfem_object(in.front()))
+          mf2 = to_meshfem_object(in.pop());
+        darray U = in.pop().to_darray();
+        in.last_popped().check_trailing_dimension(int(mf2->nb_dof()));
+        exp.write_point_data(*mf2, U, get_vtk_dataset_name(in, count));
+        count+=1;
+       }
+       );
+
 
     /*@GET ('export to dx',@str filename, ...['as', @str 
mesh_name][,'edges']['serie',@str serie_name][,'ascii'][,'append'], U, 
'name'...)
     Export a @tmf and some fields to an OpenDX file.
diff --git a/interface/src/gf_mesh_get.cc b/interface/src/gf_mesh_get.cc
index 6c9687f..9fcf011 100644
--- a/interface/src/gf_mesh_get.cc
+++ b/interface/src/gf_mesh_get.cc
@@ -1247,6 +1247,31 @@ void gf_mesh_get(getfemint::mexargs_in& m_in,
        );
 
 
+    /*@GET ('export to vtu', @str filename, ... [,'ascii'][,'quality'])
+    Exports a mesh to a VTK(XML) file .
+
+    If 'quality' is specified, an estimation of the quality of each
+    convex will be written to the file.
+
+    See also MESH_FEM:GET('export to vtu'), SLICE:GET('export to vtu').@*/
+    sub_command
+      ("export to vtu", 1, 3, 0, 1,
+       bool write_q = false; bool ascii = false;
+       std::string fname = in.pop().to_string();
+       while (in.remaining() && in.front().is_string()) {
+         std::string cmd2 = in.pop().to_string();
+         if (cmd_strmatch(cmd2, "ascii"))
+           ascii = true;
+         else if (cmd_strmatch(cmd2, "quality"))
+           write_q = true;
+         else THROW_BADARG("expecting 'ascii' or 'quality', got " << cmd2);
+       }
+       getfem::vtu_export exp(fname, ascii);
+       exp.exporting(*pmesh);
+       exp.write_mesh(); if (write_q) exp.write_mesh_quality(*pmesh);
+       );
+
+
     /*@GET ('export to dx', @str filename, ... 
[,'ascii'][,'append'][,'as',@str name,[,'serie',@str serie_name]][,'edges'])
     Exports a mesh to an OpenDX file.
 
diff --git a/interface/src/gf_slice_get.cc b/interface/src/gf_slice_get.cc
index 985072c..9a47f09 100644
--- a/interface/src/gf_slice_get.cc
+++ b/interface/src/gf_slice_get.cc
@@ -438,6 +438,78 @@ void gf_slice_get(getfemint::mexargs_in& m_in,
        );
 
 
+    /*@GET ('export to vtu', @str filename, ...)
+    Export a slice to VTK(XML).
+
+    Following the `filename`, you may use any of the following options:
+
+    - if 'ascii' is not used, the file will contain binary data
+      (non portable, but fast).
+    - if 'edges' is used, the edges of the original mesh will be
+      written instead of the slice content.
+
+    More than one dataset may be written, just list them. Each dataset
+    consists of either:
+
+    - a field interpolated on the slice (scalar, vector or tensor),
+      followed by an optional name.
+    - a mesh_fem and a field, followed by an optional name.
+
+    Examples:
+
+    - SLICE:GET('export to vtu', 'test.vtu', Usl, 'first_dataset', mf,
+      U2, 'second_dataset')
+    - SLICE:GET('export to vtu', 'test.vtu', 'ascii', mf,U2)
+    - SLICE:GET('export to vtu', 'test.vtu', 'edges', 'ascii', Uslice)@*/
+    sub_command
+      ("export to vtu",1, -1, 0, 0,
+       std::string fname = in.pop().to_string();
+       bool ascii = false;
+       bool edges = false;
+       while (in.remaining() && in.front().is_string()) {
+         std::string cmd2 = in.pop().to_string();
+         if (cmd_strmatch(cmd2, "ascii"))
+           ascii = true;
+         else if (cmd_strmatch(cmd2, "edges"))
+           edges = true;
+         else THROW_BADARG("expecting 'ascii' or 'edges', got " << cmd2);
+       }
+       getfem::vtu_export exp(fname, ascii);
+       getfem::stored_mesh_slice sl_edges;
+       const getfem::stored_mesh_slice *vtu_slice = sl;
+       getfem::mesh m_edges;
+       if (edges) {
+         vtu_slice = &sl_edges;
+         dal::bit_vector slice_edges;
+         getfem::mesh_slicer slicer(sl->linked_mesh());
+         getfem::slicer_build_edges_mesh action(m_edges,slice_edges);
+         slicer.push_back_action(action); slicer.exec(*sl);
+         sl_edges.build(m_edges, getfem::slicer_none());
+       }
+       exp.exporting(*vtu_slice);
+       exp.write_mesh();
+       int count = 1;
+       if (in.remaining()) {
+         do {
+           if (in.remaining() >= 2 && is_meshfem_object(in.front())) {
+             const getfem::mesh_fem &mf = *to_meshfem_object(in.pop());
+
+             darray U = in.pop().to_darray();
+             in.last_popped().check_trailing_dimension(int(mf.nb_dof()));
+
+             exp.write_point_data(mf,U,get_vtk_dataset_name(in, count));
+           } else if (in.remaining()) {
+             darray slU = in.pop().to_darray();
+             
in.last_popped().check_trailing_dimension(int(vtu_slice->nb_points()));
+
+             exp.write_sliced_point_data(slU,get_vtk_dataset_name(in, count));
+           } else THROW_BADARG("don't know what to do with this argument")
+               count+=1;
+         } while (in.remaining());
+       }
+       );
+
+
     /*@GET ('export to pov', @str filename)
       Export a the triangles of the slice to POV-RAY.@*/
     sub_command
diff --git a/interface/tests/python/Makefile.am 
b/interface/tests/python/Makefile.am
index 5c520df..c281cc0 100644
--- a/interface/tests/python/Makefile.am
+++ b/interface/tests/python/Makefile.am
@@ -24,6 +24,7 @@ endif
 
 EXTRA_DIST=                                            \
        check_export.py                                 \
+       check_export_vtu.py                             \
        check_global_functions.py                       \
        check_levelset.py                               \
        check_asm.py                                    \
@@ -64,6 +65,7 @@ EXTRA_DIST=                                           \
 if BUILDPYTHON
 TESTS =                                                \
        check_export.py                                 \
+       check_export_vtu.py                             \
        check_global_functions.py                       \
        check_asm.py                                    \
        check_secondary_domain.py                       \
diff --git a/interface/tests/python/check_export_vtu.py 
b/interface/tests/python/check_export_vtu.py
new file mode 100644
index 0000000..f6118ee
--- /dev/null
+++ b/interface/tests/python/check_export_vtu.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Python GetFEM interface
+#
+# Copyright (C) 2004-2020 Yves Renard, Julien Pommier.
+#
+# This file is a part of GetFEM
+#
+# GetFEM  is  free software;  you  can  redistribute  it  and/or modify it
+# under  the  terms  of the  GNU  Lesser General Public License as published
+# by  the  Free Software Foundation;  either version 2.1 of the License,  or
+# (at your option) any later version.
+# This program  is  distributed  in  the  hope  that it will be useful,  but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+# License for more details.
+# You  should  have received a copy of the GNU Lesser General Public License
+# along  with  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+############################################################################
+"""  test export.
+
+  This program is used to check that python-getfem is working. This is
+  also a good example of use of python-getfem..
+
+  $Id$
+"""
+import getfem as gf
+import numpy as np
+import pyvista as pv
+
+convex_connectivity = np.array([0, 1, 1, 2])
+mesh = gf.Mesh("cartesian", [0.0, 1.0, 2.0])
+pts = mesh.pts()[0]
+
+
+filenames = [
+    "check_mesh_ascii.vtk",
+    "check_mesh_binary.vtk",
+    "check_mesh_ascii.vtu",
+    "check_mesh_binary.vtu",
+]
+
+mesh.export_to_vtk(filenames[0], "ascii")
+mesh.export_to_vtk(filenames[1])
+mesh.export_to_vtu(filenames[2], "ascii")
+mesh.export_to_vtu(filenames[3])
+
+for filename in filenames:
+    print(filename)
+    unstructured_grid = pv.read(filename)
+
+    expected = pts
+    actual = unstructured_grid.points[:, 0]
+    np.testing.assert_equal(expected, actual, "export of mesh pts is not 
correct.")
+
+    expected = convex_connectivity
+    actual = unstructured_grid.cell_connectivity
+    np.testing.assert_equal(expected, actual, "export of mesh convex is not 
correct.")
diff --git a/requirements.txt b/requirements.txt
index 358da32..5b55979 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
 numpy
 scipy
 Sphinx
+pyvista
diff --git a/src/getfem/getfem_export.h b/src/getfem/getfem_export.h
index b4436cf..d54c0e5 100644
--- a/src/getfem/getfem_export.h
+++ b/src/getfem/getfem_export.h
@@ -78,6 +78,7 @@ namespace getfem {
     std::ofstream real_os;
     dim_type dim_;
     bool reverse_endian;
+    std::vector<unsigned char> vals;
     enum { EMPTY, HEADER_WRITTEN, STRUCTURE_WRITTEN, IN_CELL_DATA,
            IN_POINT_DATA } state;
 
@@ -85,10 +86,12 @@ namespace getfem {
     template<class V> void write_vec(V p, size_type qdim);
     template<class IT> void write_3x3tensor(IT p);
     void write_separ();
+    void clear_vals();
+    void write_vals();
 
   public:
-    vtk_export(const std::string& fname, bool ascii_= false, bool vtk_=true);
-    vtk_export(std::ostream &os_, bool ascii_ = false, bool vtk_=true);
+    vtk_export(const std::string& fname, bool ascii_ = false, bool vtk_= true);
+    vtk_export(std::ostream &os_, bool ascii_ = false, bool vtk_ = true);
     ~vtk_export(); // a vtu file is completed upon calling the destructor
     /** should be called before write_*_data */
     void exporting(const mesh& m);
@@ -156,10 +159,17 @@ namespace getfem {
     if (ascii) os << " " << v;
     else {
       char *p = (char*)&v;
-      if (reverse_endian)
-        for (size_type i=0; i < sizeof(v)/2; ++i)
-          std::swap(p[i], p[sizeof(v)-i-1]);
-      os.write(p, sizeof(T));
+      if (vtk) {
+        if (reverse_endian)
+          for (size_type i=0; i < sizeof(v)/2; ++i)
+            std::swap(p[i], p[sizeof(v)-i-1]);
+        os.write(p, sizeof(T));
+      } else {
+        union { T value; unsigned char bytes[sizeof(T)]; } UNION;
+        UNION.value = v;
+        for (size_type i=0; i < sizeof(T); i++)
+          vals.push_back(UNION.bytes[i]);
+      }
     }
   }
 
@@ -250,20 +260,19 @@ namespace getfem {
         os << "SCALARS " << remove_spaces(name) << " float 1\n"
            << "LOOKUP_TABLE default\n";
       else
-        os << "<DataArray type=\"Float32\" Name=\"" << remove_spaces(name)
-           << "\" format=\"ascii\">\n";
-      for (size_type i=0; i < nb_val; ++i) {
+        os << "<DataArray type=\"Float32\" Name=\"" << remove_spaces(name) << 
"\" "
+           << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
+      for (size_type i=0; i < nb_val; ++i)
         write_val(float(U[i]));
-      }
     } else if (Q <= 3) {
       if (vtk)
         os << "VECTORS " << remove_spaces(name) << " float\n";
       else
-        os << "<DataArray type=\"Float32\" Name=\"" << remove_spaces(name)
-           << "\" NumberOfComponents=\"3\" format=\"ascii\">\n";
-      for (size_type i=0; i < nb_val; ++i) {
+        os << "<DataArray type=\"Float32\" Name=\"" << remove_spaces(name) << 
"\" "
+           << "NumberOfComponents=\"3\" "
+           << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
+      for (size_type i=0; i < nb_val; ++i)
         write_vec(U.begin() + i*Q, Q);
-      }
     } else if (Q == gmm::sqr(dim_)) {
       /* tensors : coef are supposed to be stored in FORTRAN order
          in the VTK/VTU file, they are written with C (row major) order
@@ -272,22 +281,22 @@ namespace getfem {
         os << "TENSORS " << remove_spaces(name) << " float\n";
       else
         os << "<DataArray type=\"Float32\" Name=\"" << remove_spaces(name)
-           << "\" NumberOfComponents=\"9\" format=\"ascii\">";
-      for (size_type i=0; i < nb_val; ++i) {
+           << "\" NumberOfComponents=\"9\" "
+           << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
+      for (size_type i=0; i < nb_val; ++i)
         write_3x3tensor(U.begin() + i*Q);
-      }
     } else
       GMM_ASSERT1(false, std::string(vtk ? "vtk" : "vtu")
                          + " does not accept vectors of dimension > 3");
-    write_separ();
-    if (!vtk) os << "</DataArray>\n";
+    if (vtk) write_separ();
+    if (!vtk) os << (ascii ? "" : "\n") << "</DataArray>\n";
   }
 
 
   class vtu_export : public vtk_export {
   public:
-    vtu_export(const std::string& fname) : vtk_export(fname, true, false) {}
-    vtu_export(std::ostream &os_) : vtk_export(os_, true, false) {}
+    vtu_export(const std::string& fname, bool ascii_ = false) : 
vtk_export(fname, ascii_, false) {}
+    vtu_export(std::ostream &os_, bool ascii_ = false) : vtk_export(os_, 
ascii_, false) {}
   };
 
   /** @brief A (quite large) class for exportation of data to IBM OpenDX.
diff --git a/src/getfem_export.cc b/src/getfem_export.cc
index acfca88..0d3fe84 100644
--- a/src/getfem_export.cc
+++ b/src/getfem_export.cc
@@ -46,6 +46,36 @@ namespace getfem
     return true;
   }
 
+  /* Base64 encoding (https://en.wikipedia.org/wiki/Base64) */
+  std::string base64_encode(const std::vector<unsigned char>& src)
+  {
+    const std::string 
table("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
+    std::string dst;
+    for (size_type i = 0; i < src.size(); ++i) {
+      switch (i % 3) {
+      case 0:
+        dst.push_back(table[(src[i] & 0xFC) >> 2]);
+        if (i + 1 == src.size()) {
+          dst.push_back(table[(src[i] & 0x03) << 4]);
+          dst.push_back('=');
+          dst.push_back('=');
+        }
+        break;
+      case 1:
+        dst.push_back(table[((src[i - 1] & 0x03) << 4) | ((src[i + 0] & 0xF0) 
>> 4)]);
+        if (i + 1 == src.size()) {
+          dst.push_back(table[(src[i] & 0x0F) << 2]);
+          dst.push_back('=');
+        }
+        break;
+      case 2:
+        dst.push_back(table[((src[i - 1] & 0x0F) << 2) | ((src[i + 0] & 0xC0) 
>> 6)]);
+        dst.push_back(table[src[i] & 0x3F]);
+        break;
+      }
+    }
+    return dst;
+  }
 
   /* -------------------------------------------------------------
    * VTK export
@@ -189,12 +219,12 @@ namespace getfem
   }
 
   void vtk_export::init() {
-    GMM_ASSERT1(vtk || ascii, "vtu support only ascii format.");
     strcpy(header, "Exported by GetFEM");
     psl = 0; dim_ = dim_type(-1);
     static int test_endian = 0x01234567;
     reverse_endian = (*((char*)&test_endian) == 0x67);
     state = EMPTY;
+    clear_vals();
   }
 
   void vtk_export::switch_to_cell_data() {
@@ -368,7 +398,8 @@ namespace getfem
       os << (ascii ? "ASCII\n" : "BINARY\n");
     } else {
       os << "<?xml version=\"1.0\"?>\n";
-      os << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\">\n";
+      os << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" ";
+      os << "byte_order=\"" << (reverse_endian ? "LittleEndian" : "BigEndian") 
<< "\">\n";
       os << "<!--" << header << "-->\n";
       os << "<UnstructuredGrid>\n";
     }
@@ -378,6 +409,16 @@ namespace getfem
   void vtk_export::write_separ()
   { if (ascii) os << "\n"; }
 
+  void vtk_export::clear_vals()
+  { if (!vtk && !ascii) vals.clear(); }
+
+  void vtk_export::write_vals() {
+    if (!vtk && !ascii) {
+      os << base64_encode(vals);
+      clear_vals();
+    }
+  }
+
   void vtk_export::write_mesh() {
     if (psl) write_mesh_structure_from_slice();
     else write_mesh_structure_from_mesh_fem();
@@ -405,7 +446,8 @@ namespace getfem
       os << "\" NumberOfCells=\"" << splx_cnt << "\">\n";
       os << "<Points>\n";
       os << "<DataArray type=\"Float32\" Name=\"Points\" ";
-      os << "NumberOfComponents=\"3\" format=\"ascii\">\n";
+      os << "NumberOfComponents=\"3\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
     }
     /*
        points are not merge, vtk is mostly fine with that (except for
@@ -417,8 +459,9 @@ namespace getfem
        write_vec(psl->nodes(ic)[i].pt.begin(),psl->nodes(ic)[i].pt.size());
       write_separ();
     }
+    write_vals();
     if (!vtk) {
-      os << "</DataArray>\n";
+      os << (ascii ? "" : "\n") << "</DataArray>\n";
       os << "</Points>\n";
     }
 
@@ -428,53 +471,58 @@ namespace getfem
       write_separ(); os << "CELLS " << splx_cnt << " " << cells_cnt << "\n";
     } else {
       os << "<Cells>\n";
-      os << "<DataArray type=\"Int64\" Name=\"connectivity\" 
format=\"ascii\">\n";
+      os << "<DataArray type=\"Int32\" Name=\"connectivity\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
     }
     for (size_type ic=0; ic < psl->nb_convex(); ++ic) {
       const getfem::mesh_slicer::cs_simplexes_ct& s = psl->simplexes(ic);
-      for (size_type i=0; i < s.size(); ++i) {
+      for (const auto &val : s) {
         if (vtk) {
-          write_val(int(s[i].dim()+1));
+          write_val(int(val.dim()+1));
         }
-        for (size_type j=0; j < s[i].dim()+1; ++j)
-          write_val(int(s[i].inodes[j] + nodes_cnt));
+        for (size_type j=0; j < val.dim()+1; ++j)
+          write_val(int(val.inodes[j] + nodes_cnt));
         write_separ();
       }
       nodes_cnt += psl->nodes(ic).size();
     }
     assert(nodes_cnt == psl->nb_points()); // sanity check
+    write_vals();
     if (vtk) {
       write_separ(); os << "CELL_TYPES " << splx_cnt << "\n";
     } else {
-      os << "</DataArray>\n";
-      os << "<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">\n";
+      os << (ascii ? "" : "\n") << "</DataArray>\n";
+      os << "<DataArray type=\"Int32\" Name=\"offsets\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
     }
     int cnt = 0;
     for (size_type ic=0; ic < psl->nb_convex(); ++ic) {
       const getfem::mesh_slicer::cs_simplexes_ct& s = psl->simplexes(ic);
-      for (size_type i=0; i < s.size(); ++i) {
+      for (const auto &val : s)
         if (vtk) {
-          write_val(int(vtk_simplex_code[s[i].dim()]));
+          write_val(int(vtk_simplex_code[val.dim()]));
         } else {
-          cnt += int(s[i].dim()+1);
+          cnt += int(val.dim()+1);
           write_val(cnt);
         }
-      }
       write_separ();
       splx_cnt -= s.size();
     }
+    write_vals();
     assert(splx_cnt == 0); // sanity check
     if (!vtk) {
-      os << "</DataArray>\n";
-      os << "<DataArray type=\"Int64\" Name=\"types\" format=\"ascii\">\n";
+      os << (ascii ? "" : "\n") << "</DataArray>\n";
+      os << "<DataArray type=\"Int32\" Name=\"types\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
       for (size_type ic=0; ic < psl->nb_convex(); ++ic) {
         const getfem::mesh_slicer::cs_simplexes_ct& s = psl->simplexes(ic);
         for (size_type i=0; i < s.size(); ++i) {
           write_val(int(vtk_simplex_code[s[i].dim()]));
         }
       }
-      os << "</DataArray>\n"
-         << "</Cells>\n";
+      write_vals();
+      os << (ascii ? "" : "\n") << "</DataArray>\n";
+      os << "</Cells>\n";
     }
     state = STRUCTURE_WRITTEN;
   }
@@ -492,16 +540,20 @@ namespace getfem
          << "\" NumberOfCells=\"" << pmf->convex_index().card() << "\">\n";
       os << "<Points>\n";
       os << "<DataArray type=\"Float32\" Name=\"Points\" ";
-      os << "NumberOfComponents=\"3\" format=\"ascii\">\n";
+      os << "NumberOfComponents=\"3\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
     }
     std::vector<int> dofmap(pmf->nb_dof());
     int cnt = 0;
+    int size = int(sizeof(float)*pmf_dof_used.card()*3);
+    if (!vtk && !ascii) write_val(size);
     for (dal::bv_visitor d(pmf_dof_used); !d.finished(); ++d) {
       dofmap[d] = cnt++;
       base_node P = pmf->point_of_basic_dof(d);
       write_vec(P.const_begin(),P.size());
       write_separ();
     }
+    write_vals();
 
     size_type nb_cell_values = 0;
     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv)
@@ -511,10 +563,19 @@ namespace getfem
       write_separ();
       os << "CELLS " << pmf->convex_index().card() << " " << nb_cell_values << 
"\n";
     } else {
-      os << "</DataArray>\n";
+      os << (ascii ? "" : "\n") << "</DataArray>\n";
       os << "</Points>\n";
       os << "<Cells>\n";
-      os << "<DataArray type=\"Int64\" Name=\"connectivity\" 
format=\"ascii\">\n";
+      os << "<DataArray type=\"Int32\" Name=\"connectivity\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
+      if (!vtk && !ascii) {
+        size = 0;
+        for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
+          const std::vector<unsigned> &dmap = 
select_vtk_dof_mapping(pmf_mapping_type[cv]);
+          size += int(sizeof(int)*dmap.size());
+        }
+        write_val(size);
+      }
     }
 
     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
@@ -524,30 +585,44 @@ namespace getfem
         write_val(int(dofmap[pmf->ind_basic_dof_of_element(cv)[dmap[i]]]));
       write_separ();
     }
+    write_vals();
 
     if (vtk) {
       write_separ();
       os << "CELL_TYPES " << pmf->convex_index().card() << "\n";
     } else {
-      os << "</DataArray>\n";
-      os << "<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">\n";
+      os << (ascii ? "" : "\n") << "</DataArray>\n";
+      os << "<DataArray type=\"Int32\" Name=\"offsets\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
+      if (!vtk && !ascii) {
+        size = 0;
+        for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv)
+          size += int(sizeof(int));
+        write_val(size);
+      }
       cnt = 0;
       for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
         const std::vector<unsigned> &dmap = 
select_vtk_dof_mapping(pmf_mapping_type[cv]);
         cnt += int(dmap.size());
         write_val(cnt);
-        write_separ();
       }
-      os << "</DataArray>\n";
-      os << "<DataArray type=\"Int64\" Name=\"types\" format=\"ascii\">\n";
+      write_vals();
+      os << "\n" << "</DataArray>\n";
+      os << "<DataArray type=\"Int32\" Name=\"types\" ";
+      os << (ascii ? "format=\"ascii\">\n" : "format=\"binary\">\n");
+      if (!ascii) {
+        size = 0;
+        for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv)
+          size += int(sizeof(int));
+        write_val(size);
+      }
     }
     for (dal::bv_visitor cv(pmf->convex_index()); !cv.finished(); ++cv) {
-      write_val(select_vtk_type(pmf_mapping_type[cv]));
-      write_separ();
+      write_val(int(select_vtk_type(pmf_mapping_type[cv])));
+      if (vtk) write_separ();
     }
-    if (!vtk)
-      os << "</DataArray>\n"
-         << "</Cells>\n";
+    write_vals();
+    if (!vtk) os << "\n" << "</DataArray>\n" << "</Cells>\n";
 
     state = STRUCTURE_WRITTEN;
   }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]