diff src/Mesh.cc @ 258:ab35a8b0deef

Support storage of mesh markers via meshfunction
author Eugenio Gianniti <eugenio.gianniti@mail.polimi.it>
date Fri, 01 Aug 2014 18:59:18 +0200
parents fb67b636616f
children 68cae2998775
line wrap: on
line diff
--- a/src/Mesh.cc	Wed Jul 30 21:09:52 2014 +0200
+++ b/src/Mesh.cc	Fri Aug 01 18:59:18 2014 +0200
@@ -16,13 +16,22 @@
 */
 
 #include "mesh.h"
+#include "meshfunction.h"
 #include "dolfin_compat.h"
 #ifdef LATEST_DOLFIN
 #include <dolfin/mesh/MeshPartitioning.h>
 #endif
 
-DEFUN_DLD (Mesh, args, ,"-*- texinfo -*-\n\
-@deftypefn {Function File} {[@var{mesh_out}]} = \
+octave_value
+compute_facet_markers (dolfin::Mesh const &, Array <octave_idx_type> const &,
+                       std::size_t const);
+octave_value
+compute_cell_markers (dolfin::Mesh const &, Array <octave_idx_type> const &,
+                      std::size_t const);
+
+DEFUN_DLD (Mesh, args, nargout,"-*- texinfo -*-\n\
+@deftypefn {Function File} {[@var{mesh_out}, \
+@var{facet_markers}, @var{cell_markers}]} = \
 Mesh (@var{mesh_in}) \n\
 Construct a mesh from file or from (p, e, t) format.\n\
 The @var{mesh_in} should be either\n\
@@ -31,18 +40,21 @@
 is stored in .xml file\n\
 If the file is not a .xml file you can try to use the command\
 dolfin-convert directly from the terminal. \n\
-@item a a PDE-tool like structure with matrix fields (p,e,t)\
+@item a PDE-tool like structure with matrix fields (p,e,t)\
 @end itemize\n\
 The output @var{mesh_out} is a representation of the\
 @var{mesh_in} which is compatible with fem-fenics.\n\
+Optional outputs @var{facet_markers} and @var{cell_markers} \
+are MeshFunctions holding the markers extracted from the PDE-tool \
+representation. \n\
 The easiest way for dealing with meshes is using the msh pkg. \n\
-@seealso{FunctionSpace}\n\
+@seealso{FunctionSpace, DirichletBC}\n\
 @end deftypefn")
 {
   int nargin = args.length ();
-  octave_value retval = 0;
+  octave_value_list retval;
 
-  if (nargin < 1 || nargin > 1)
+  if (nargin < 1 || nargin > 1 || nargout > 3)
     print_usage ();
   else
     {
@@ -60,7 +72,7 @@
             {
               std::string filename = args(0).string_value ();
               //if the filename is not valid, dolfin takes care of it
-              retval = new mesh (filename);
+              retval(0) = new mesh (filename);
             }
 
           else if (args(0).is_map () == true)
@@ -72,7 +84,26 @@
 
               if (! error_state)
                 {
-                  retval = new mesh (p, e, t);
+                  retval(0) = new mesh (p, e, t);
+
+                  if (nargout >= 2)
+                    {
+                      if (! meshfunction_type_loaded)
+                        {
+                          meshfunction::register_type ();
+                          meshfunction_type_loaded = true;
+                          mlock ();
+                        }
+
+                      mesh const & msh_ov =
+                        static_cast <mesh const &> (retval(0).get_rep ());
+                      dolfin::Mesh const & msh = msh_ov.get_msh ();
+                      std::size_t const D = p.rows ();
+
+                      retval(1) = compute_facet_markers (msh, e, D);
+                      if (nargout == 3)
+                        retval(2) = compute_cell_markers (msh, t, D);
+                    }
                 }
             }
 
@@ -136,14 +167,14 @@
       dolfin::MeshValueCollection<std::size_t> facet(*msh, D - 1);
       std::size_t num_side_edges = e.cols ();
 
-      unsigned const num_procs =
+      unsigned const size =
 #ifdef LATEST_DOLFIN
         dolfin::MPI::size (MPI_COMM_WORLD);
 #else
         dolfin::MPI::num_processes ();
 #endif
 
-      if (num_procs == 1)
+      if (size == 1)
         {
           if (D == 2)
             {
@@ -202,11 +233,10 @@
             }
         }
 
-
       dolfin::MeshValueCollection<std::size_t> cell (*msh, D);
       std::size_t num_cells = t.cols ();
 
-      if (num_procs == 1)
+      if (size == 1)
         {
           if (D == 2)
             {
@@ -364,3 +394,298 @@
       pmsh = msh;
     }
 }
+
+octave_value
+compute_facet_markers (dolfin::Mesh const & _msh,
+                       Array <octave_idx_type> const & e,
+                       std::size_t const D)
+{
+  dolfin::MeshFunction <std::size_t> facet (_msh, D-1, 0);
+  std::size_t const num_side_edges = e.cols ();
+  std::vector <std::size_t> const & global_vertices =
+    _msh.topology ().global_indices (0);
+  std::vector <std::size_t> const & global_facets =
+    _msh.topology ().global_indices (D-1);
+
+  if (D == 2)
+    {
+      for (std::size_t i = 0; i < num_side_edges; ++i)
+        {
+          std::size_t local_vertex = 0;
+          std::size_t const e_index = e.xelem (0, i) - 1;
+          while (local_vertex < global_vertices.size () &&
+                 e_index != global_vertices[local_vertex])
+            ++local_vertex;
+
+          if (local_vertex < global_vertices.size ())
+            {
+              dolfin::Vertex v (_msh, local_vertex);
+              for (dolfin::FacetIterator f (v); ! f.end (); ++f)
+                {
+                  std::size_t const & vertex0 =
+                    global_vertices[f->entities(0)[0]];
+                  std::size_t const & vertex1 =
+                    global_vertices[f->entities(0)[1]];
+
+                  if (vertex0 == e.xelem (0, i) - 1
+                      && vertex1 == e.xelem (1, i) - 1
+                      || vertex0 == e.xelem (1, i) - 1
+                      && vertex1 == e.xelem (0, i) - 1)
+                    {
+                      facet[*f] = e.xelem (4, i);
+                      break;
+                    }
+                }
+            }
+        }
+    }
+
+  if (D == 3)
+    {
+      for (std::size_t i = 0; i < num_side_edges; ++i)
+        {
+          std::size_t local_vertex = 0;
+          std::size_t const e_index = e.xelem (0, i) - 1;
+          while (local_vertex < global_vertices.size () &&
+                 e_index != global_vertices[local_vertex])
+            ++local_vertex;
+
+          if (local_vertex < global_vertices.size ())
+            {
+              dolfin::Vertex v (_msh, local_vertex);
+              for (dolfin::FacetIterator f (v); ! f.end (); ++f)
+                {
+                  std::size_t const & vertex0 =
+                    global_vertices[f->entities(0)[0]];
+                  std::size_t const & vertex1 =
+                    global_vertices[f->entities(0)[1]];
+                  std::size_t const & vertex2 =
+                    global_vertices[f->entities(0)[2]];
+
+                  if (vertex0 == e(0, i) - 1
+                      && vertex1 == e.xelem (1, i) - 1
+                      && vertex2 == e.xelem (2, i) - 1
+                      || vertex0 == e.xelem (0, i) - 1
+                      && vertex1 == e.xelem (2, i) - 1
+                      && vertex2 == e.xelem (1, i) - 1
+                      || vertex0 == e.xelem (1, i) - 1
+                      && vertex1 == e.xelem (0, i) - 1
+                      && vertex2 == e.xelem (2, i) - 1
+                      || vertex0 == e.xelem (1, i) - 1
+                      && vertex1 == e.xelem (2, i) - 1
+                      && vertex2 == e.xelem (0, i) - 1
+                      || vertex0 == e.xelem (2, i) - 1
+                      && vertex1 == e.xelem (0, i) - 1
+                      && vertex2 == e.xelem (1, i) - 1
+                      || vertex0 == e.xelem (2, i) - 1
+                      && vertex1 == e.xelem (1, i) - 1
+                      && vertex2 == e.xelem (0, i) - 1)
+                    {
+                      facet[*f] = e.xelem (9, i);
+                      break;
+                    }
+                }
+            }
+        }
+    }
+
+  octave_value retval = new meshfunction (facet);
+  return retval;
+}
+
+octave_value
+compute_cell_markers (dolfin::Mesh const & _msh,
+                      Array <octave_idx_type> const & t,
+                      std::size_t const D)
+{
+  dolfin::MeshFunction <std::size_t> cell (_msh, D, 0);
+  std::size_t const num_cells = t.cols ();
+  std::vector <std::size_t> const & global_vertices =
+    _msh.topology ().global_indices (0);
+  std::vector <std::size_t> const & global_cells =
+    _msh.topology ().global_indices (D);
+
+  if (D == 2)
+    {
+      for (std::size_t i = 0; i < num_cells; ++i)
+        {
+          std::size_t local_vertex = 0;
+          std::size_t const t_index = t.xelem (0, i) - 1;
+          while (local_vertex < global_vertices.size () &&
+                 t_index != global_vertices[local_vertex])
+            ++local_vertex;
+
+          if (local_vertex < global_vertices.size ())
+            {
+              dolfin::Vertex v (_msh, local_vertex);
+              for (dolfin::CellIterator f (v); ! f.end (); ++f)
+                {
+                  std::size_t const & vertex0 =
+                    global_vertices[f->entities(0)[0]];
+                  std::size_t const & vertex1 =
+                    global_vertices[f->entities(0)[1]];
+                  std::size_t const & vertex2 =
+                    global_vertices[f->entities(0)[2]];
+
+                  if (vertex0 == t.xelem (0, i) - 1
+                      && vertex1 == t.xelem (1, i) - 1
+                      && vertex2 == t.xelem (2, i) - 1
+                      || vertex0 == t.xelem (0, i) - 1
+                      && vertex1 == t.xelem (2, i) - 1
+                      && vertex2 == t.xelem (1, i) - 1
+                      || vertex0 == t.xelem (1, i) - 1
+                      && vertex1 == t.xelem (0, i) - 1
+                      && vertex2 == t.xelem (2, i) - 1
+                      || vertex0 == t.xelem (1, i) - 1
+                      && vertex1 == t.xelem (2, i) - 1
+                      && vertex2 == t.xelem (0, i) - 1
+                      || vertex0 == t.xelem (2, i) - 1
+                      && vertex1 == t.xelem (0, i) - 1
+                      && vertex2 == t.xelem (1, i) - 1
+                      || vertex0 == t.xelem (2, i) - 1
+                      && vertex1 == t.xelem (1, i) - 1
+                      && vertex2 == t.xelem (0, i) - 1)
+                    {
+                      cell[*f] = t.xelem (3, i);
+                      break;
+                    }
+                }
+            }
+        }
+    }
+
+  if (D == 3)
+    {
+      for (std::size_t i = 0; i < num_cells; ++i)
+        {
+          std::size_t local_vertex = 0;
+          std::size_t const t_index = t.xelem (0, i) - 1;
+          while (local_vertex < global_vertices.size () &&
+                 t_index != global_vertices[local_vertex])
+            ++local_vertex;
+
+          if (local_vertex < global_vertices.size ())
+            {
+              dolfin::Vertex v (_msh, local_vertex);
+              for (dolfin::CellIterator f (v); ! f.end (); ++f)
+                {
+                  std::size_t const & vertex0 =
+                    global_vertices[f->entities(0)[0]];
+                  std::size_t const & vertex1 =
+                    global_vertices[f->entities(0)[1]];
+                  std::size_t const & vertex2 =
+                    global_vertices[f->entities(0)[2]];
+                  std::size_t const & vertex3 =
+                    global_vertices[f->entities(0)[3]];
+
+                  if (vertex0 == t.xelem (0, i) - 1
+                       && vertex1 == t.xelem (1, i) - 1
+                       && vertex2 == t.xelem (2, i) - 1
+                       && vertex3 == t.xelem (3, i) - 1
+                       || vertex0 == t.xelem (0, i) - 1
+                       && vertex1 == t.xelem (1, i) - 1
+                       && vertex2 == t.xelem (3, i) - 1
+                       && vertex3 == t.xelem (2, i) - 1
+                       || vertex0 == t.xelem (0, i) - 1
+                       && vertex1 == t.xelem (2, i) - 1
+                       && vertex2 == t.xelem (1, i) - 1
+                       && vertex3 == t.xelem (3, i) - 1
+                       || vertex0 == t.xelem (0, i) - 1
+                       && vertex1 == t.xelem (2, i) - 1
+                       && vertex2 == t.xelem (3, i) - 1
+                       && vertex3 == t.xelem (1, i) - 1
+                       || vertex0 == t.xelem (0, i) - 1
+                       && vertex1 == t.xelem (3, i) - 1
+                       && vertex2 == t.xelem (1, i) - 1
+                       && vertex3 == t.xelem (2, i) - 1
+                       || vertex0 == t.xelem (0, i) - 1
+                       && vertex1 == t.xelem (3, i) - 1
+                       && vertex2 == t.xelem (2, i) - 1
+                       && vertex3 == t.xelem (1, i) - 1
+
+                       || vertex0 == t.xelem (1, i) - 1
+                       && vertex1 == t.xelem (0, i) - 1
+                       && vertex2 == t.xelem (2, i) - 1
+                       && vertex3 == t.xelem (3, i) - 1
+                       || vertex0 == t.xelem (1, i) - 1
+                       && vertex1 == t.xelem (0, i) - 1
+                       && vertex2 == t.xelem (3, i) - 1
+                       && vertex3 == t.xelem (2, i) - 1
+                       || vertex0 == t.xelem (1, i) - 1
+                       && vertex1 == t.xelem (2, i) - 1
+                       && vertex2 == t.xelem (0, i) - 1
+                       && vertex3 == t.xelem (3, i) - 1
+                       || vertex0 == t.xelem (1, i) - 1
+                       && vertex1 == t.xelem (2, i) - 1
+                       && vertex2 == t.xelem (3, i) - 1
+                       && vertex3 == t.xelem (0, i) - 1
+                       || vertex0 == t.xelem (1, i) - 1
+                       && vertex1 == t.xelem (3, i) - 1
+                       && vertex2 == t.xelem (0, i) - 1
+                       && vertex3 == t.xelem (2, i) - 1
+                       || vertex0 == t.xelem (1, i) - 1
+                       && vertex1 == t.xelem (3, i) - 1
+                       && vertex2 == t.xelem (2, i) - 1
+                       && vertex3 == t.xelem (0, i) - 1
+
+                       || vertex0 == t.xelem (2, i) - 1
+                       && vertex1 == t.xelem (0, i) - 1
+                       && vertex2 == t.xelem (1, i) - 1
+                       && vertex3 == t.xelem (3, i) - 1
+                       || vertex0 == t.xelem (2, i) - 1
+                       && vertex1 == t.xelem (0, i) - 1
+                       && vertex2 == t.xelem (3, i) - 1
+                       && vertex3 == t.xelem (1, i) - 1
+                       || vertex0 == t.xelem (2, i) - 1
+                       && vertex1 == t.xelem (1, i) - 1
+                       && vertex2 == t.xelem (0, i) - 1
+                       && vertex3 == t.xelem (3, i) - 1
+                       || vertex0 == t.xelem (2, i) - 1
+                       && vertex1 == t.xelem (1, i) - 1
+                       && vertex2 == t.xelem (3, i) - 1
+                       && vertex3 == t.xelem (0, i) - 1
+                       || vertex0 == t.xelem (2, i) - 1
+                       && vertex1 == t.xelem (3, i) - 1
+                       && vertex2 == t.xelem (0, i) - 1
+                       && vertex3 == t.xelem (1, i) - 1
+                       || vertex0 == t.xelem (2, i) - 1
+                       && vertex1 == t.xelem (3, i) - 1
+                       && vertex2 == t.xelem (1, i) - 1
+                       && vertex3 == t.xelem (0, i) - 1
+
+                       || vertex0 == t.xelem (3, i) - 1
+                       && vertex1 == t.xelem (0, i) - 1
+                       && vertex2 == t.xelem (1, i) - 1
+                       && vertex3 == t.xelem (2, i) - 1
+                       || vertex0 == t.xelem (3, i) - 1
+                       && vertex1 == t.xelem (0, i) - 1
+                       && vertex2 == t.xelem (2, i) - 1
+                       && vertex3 == t.xelem (1, i) - 1
+                       || vertex0 == t.xelem (3, i) - 1
+                       && vertex1 == t.xelem (1, i) - 1
+                       && vertex2 == t.xelem (0, i) - 1
+                       && vertex3 == t.xelem (2, i) - 1
+                       || vertex0 == t.xelem (3, i) - 1
+                       && vertex1 == t.xelem (1, i) - 1
+                       && vertex2 == t.xelem (2, i) - 1
+                       && vertex3 == t.xelem (0, i) - 1
+                       || vertex0 == t.xelem (3, i) - 1
+                       && vertex1 == t.xelem (2, i) - 1
+                       && vertex2 == t.xelem (0, i) - 1
+                       && vertex3 == t.xelem (1, i) - 1
+                       || vertex0 == t.xelem (3, i) - 1
+                       && vertex1 == t.xelem (2, i) - 1
+                       && vertex2 == t.xelem (1, i) - 1
+                       && vertex3 == t.xelem (0, i) - 1)
+                    {
+                      cell[*f] = t.xelem (4, i);
+                      break;
+                    }
+                }
+            }
+        }
+    }
+
+  octave_value retval = new meshfunction (cell);
+  return retval;
+}