[cig-commits] r14926 - in short/3D/PyLith/trunk: libsrc/topology modulesrc/include modulesrc/topology playpen/memcheck pylith pylith/perf pylith/topology

knepley at geodynamics.org knepley at geodynamics.org
Fri May 8 11:26:10 PDT 2009


Author: knepley
Date: 2009-05-08 11:26:09 -0700 (Fri, 08 May 2009)
New Revision: 14926

Added:
   short/3D/PyLith/trunk/pylith/perf/
   short/3D/PyLith/trunk/pylith/perf/Logger.py
   short/3D/PyLith/trunk/pylith/perf/Material.py
   short/3D/PyLith/trunk/pylith/perf/Memory.py
   short/3D/PyLith/trunk/pylith/perf/MemoryLogger.py
   short/3D/PyLith/trunk/pylith/perf/Mesh.py
   short/3D/PyLith/trunk/pylith/perf/VertexGroup.py
   short/3D/PyLith/trunk/pylith/perf/__init__.py
Modified:
   short/3D/PyLith/trunk/libsrc/topology/Mesh.cc
   short/3D/PyLith/trunk/libsrc/topology/Mesh.hh
   short/3D/PyLith/trunk/modulesrc/include/chararray.i
   short/3D/PyLith/trunk/modulesrc/topology/Mesh.i
   short/3D/PyLith/trunk/playpen/memcheck/memory_usage.py
   short/3D/PyLith/trunk/pylith/Makefile.am
   short/3D/PyLith/trunk/pylith/topology/Mesh.py
Log:
More memory benchmarking


Modified: short/3D/PyLith/trunk/libsrc/topology/Mesh.cc
===================================================================
--- short/3D/PyLith/trunk/libsrc/topology/Mesh.cc	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/libsrc/topology/Mesh.cc	2009-05-08 18:26:09 UTC (rev 14926)
@@ -74,5 +74,42 @@
 { // initialize
 } // initialize
 
+// ----------------------------------------------------------------------
+// Return the names of all vertex groups.
+void
+pylith::topology::Mesh::groups(int *numNames, char ***outNames)
+{ // groups
+  const ALE::Obj<std::set<std::string> >& sectionNames =  _mesh->getIntSections();
+  
+  *numNames = sectionNames->size();
+  PetscErrorCode ierr = PetscMalloc((*numNames) * sizeof(char *), outNames);
+  const std::set<std::string>::const_iterator namesEnd = sectionNames->end();
+  int i = 0;
+  for (std::set<std::string>::const_iterator name = sectionNames->begin(); name != namesEnd; ++name) {
+    char *newName;
 
+    ierr = PetscStrallocpy(name->c_str(), &newName);
+    (*outNames)[i++] = newName;
+  }
+} // groups
+
+// ----------------------------------------------------------------------
+// Return the names of all vertex groups.
+int
+pylith::topology::Mesh::groupSize(const char *name)
+{ // groupSize
+  const ALE::Obj<IntSection>&            group    = _mesh->getIntSection(name);
+  const IntSection::chart_type&          chart    = group->getChart();
+  IntSection::chart_type::const_iterator chartEnd = chart.end();
+  int                                    size     = 0;
+
+  for(IntSection::chart_type::const_iterator c_iter = chart.begin(); c_iter != chartEnd; ++c_iter) {
+    if (group->getFiberDimension(*c_iter)) {
+      size++;
+    }
+  }
+  return size;
+} // groupSize
+
+
 // End of file 

Modified: short/3D/PyLith/trunk/libsrc/topology/Mesh.hh
===================================================================
--- short/3D/PyLith/trunk/libsrc/topology/Mesh.hh	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/libsrc/topology/Mesh.hh	2009-05-08 18:26:09 UTC (rev 14926)
@@ -158,6 +158,18 @@
    */
   void view(const char* label);
 
+  /** Return the names of all vertex groups.
+   *
+   * @returns the names of al lvertex groups.
+   */
+  void groups(int *numNames, char ***outNames);
+
+  /** Return the size of a group.
+   *
+   * @returns the number of vertices in the group
+   */
+  int groupSize(const char *name);
+
 // PRIVATE MEMBERS //////////////////////////////////////////////////////
 private :
 

Modified: short/3D/PyLith/trunk/modulesrc/include/chararray.i
===================================================================
--- short/3D/PyLith/trunk/modulesrc/include/chararray.i	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/modulesrc/include/chararray.i	2009-05-08 18:26:09 UTC (rev 14926)
@@ -95,5 +95,21 @@
   delete[] $2;
 }
 
+%typemap(argout) (int *numNames, char ***outNames) {
+  int       num   = *$1;
+  char    **names = *$2;
+  PyObject *l     = PyList_New(num);
 
+  for(Py_ssize_t i = 0; i < (Py_ssize_t) num; ++i) {
+    PyList_SetItem(l, i, PyString_FromString(names[i]));
+    PetscFree(names[i]);
+  }
+  PetscFree(names);
+  $result = l;
+}
+%typemap(in,numinputs=0) (int *numNames, char ***outNames)(int tempI, char **tempC) {
+    $1 = &tempI;
+    $2 = &tempC;
+}
+
 // End of file

Modified: short/3D/PyLith/trunk/modulesrc/topology/Mesh.i
===================================================================
--- short/3D/PyLith/trunk/modulesrc/topology/Mesh.i	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/modulesrc/topology/Mesh.i	2009-05-08 18:26:09 UTC (rev 14926)
@@ -115,6 +115,18 @@
        */
       void view(const char* label);
 
+      /** Return the names of all vertex groups.
+       *
+       * @returns an array of all vertex group names
+       */
+      void groups(int *numNames, char ***outNames);
+
+      /** Return the size of a group.
+       *
+       * @returns the number of vertices in the group
+       */
+      int groupSize(const char *name);
+
     }; // Mesh
 
   } // topology

Modified: short/3D/PyLith/trunk/playpen/memcheck/memory_usage.py
===================================================================
--- short/3D/PyLith/trunk/playpen/memcheck/memory_usage.py	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/playpen/memcheck/memory_usage.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -110,7 +110,8 @@
 
 # ----------------------------------------------------------------------
 # VertexGroup class
-class VertexGroup(Component):
+import pylith.perf.VertexGroup
+class VertexGroup(Component,pylith.perf.VertexGroup.VertexGroup):
   """
   Mesh object for holding vertex group size information.
   """
@@ -148,17 +149,7 @@
     Constructor.
     """
     Component.__init__(self, name)
-    self.size = 0
     return
-
-
-  def tabulate(self, mesh):
-    """
-    Tabulate memory use.
-    """
-    nvertices = mesh.nvertices
-    nbytes = sizeInt * ( 2 * nvertices + nvertices)
-    return nbytes
   
 
   # PRIVATE METHODS ////////////////////////////////////////////////////
@@ -168,8 +159,7 @@
     Setup members using inventory.
     """
     Component._configure(self)
-    self.label = self.inventory.label
-    self.size = self.inventory.size
+    pylith.perf.VertexGroup.VertexGroup.__init__(self, self.inventory.label, self.inventory.size)
     return
 
 
@@ -311,7 +301,7 @@
     print "    Stratification: %d bytes (%.3f MB)" % \
           (memory['stratification'],
            memory['stratification'] / megabyte)
-    print "    Coordinates:     %d bytes (%.3f MB)" % \
+    print "    Coordinates:    %d bytes (%.3f MB)" % \
           (memory['coordinates'],
            memory['coordinates'] / megabyte)
     print "    Materials:      %d bytes (%.3f MB)" % \
@@ -327,7 +317,7 @@
     for (label, nbytes) in self.memory['materials'].items():
       print "    %s: %d bytes (%.3f MB)" % \
             (label, nbytes, nbytes / megabyte)
-    print "  TOTAL:           %d bytes (%.3f MB)" % \
+    print "  TOTAL:            %d bytes (%.3f MB)" % \
           (self.memory['total'], self.memory['total'] / megabyte)
 
     return
@@ -361,7 +351,7 @@
     # groups
     memory['groups'] = {}
     for group in self.groups.components():
-      nbytes = group.tabulate(self.mesh)
+      nbytes = group.tabulate()
       total += nbytes
       memory['groups'][group.label] = nbytes
 

Modified: short/3D/PyLith/trunk/pylith/Makefile.am
===================================================================
--- short/3D/PyLith/trunk/pylith/Makefile.am	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/pylith/Makefile.am	2009-05-08 18:26:09 UTC (rev 14926)
@@ -89,6 +89,7 @@
 	perf/MemoryLogger.py \
 	perf/Mesh.py \
 	perf/Material.py \
+	perf/VertexGroup.py \
 	problems/__init__.py \
 	problems/Explicit.py \
 	problems/Formulation.py \

Added: short/3D/PyLith/trunk/pylith/perf/Logger.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/Logger.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/Logger.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+#
+# ----------------------------------------------------------------------
+#
+#                           Brad T. Aagaard
+#                        U.S. Geological Survey
+#
+# <LicenseText>
+#
+# ----------------------------------------------------------------------
+#
+
+## @file pylith/perf/Logger.py
+##
+## @brief Python abstract base class for performance and memory logging.
+##
+## Factory: perf_logger.
+
+from pylith.utils.PetscComponent import PetscComponent
+
+# Logger class
+class Logger(PetscComponent):
+  """
+  Python abstract base class for performance and memory logging.
+
+  Factory: perf_logger.
+  """
+  
+  # INVENTORY //////////////////////////////////////////////////////////
+
+  class Inventory(PetscComponent.Inventory):
+    """
+    Python object for managing Problem facilities and properties.
+    """
+
+    ## @class Inventory
+    ## Python object for managing Problem facilities and properties.
+    ##
+    ## \b Properties
+    ## @li \b verbose Should information be printed to the screen.
+
+    import pyre.inventory
+
+    verbose = pyre.inventory.bool("verbose", default=True)
+    verbose.meta['tip'] = "Print information to the screen."
+
+  # PUBLIC METHODS /////////////////////////////////////////////////////
+
+  def __init__(self, name="perf_logger"):
+    """
+    Constructor.
+    """
+    PetscComponent.__init__(self, name, facility="perf_logger")
+    return
+
+  def join(self, logger):
+    """
+    Incorporate information from another logger.
+    """
+    raise NotImplementedError, "join() not implemented."
+    return
+
+  def logMesh(self, stage, mesh):
+    """
+    Read mesh parameters to determine memory from our model.
+    """
+    raise NotImplementedError, "logMesh() not implemented."
+    return
+  
+
+  # PRIVATE METHODS ////////////////////////////////////////////////////
+
+  def _configure(self):
+    """
+    Set members based using inventory.
+    """
+    PetscComponent._configure(self)
+    self.verbose = self.inventory.verbose
+    return
+
+
+  def _setupLogging(self):
+    """
+    Setup event logging.
+    """
+    return
+  
+
+# FACTORIES ////////////////////////////////////////////////////////////
+
+def perf_logger():
+  """
+  Factory associated with Logger.
+  """
+  return Logger()
+
+
+# End of file 

Added: short/3D/PyLith/trunk/pylith/perf/Material.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/Material.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/Material.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+from Memory import Memory
+
+class Material(Memory):
+  """
+  Mesh object for holding material memory and performance information.
+  """
+  def __init__(self, label = '', numCells = 0):
+    """
+    Constructor.
+    """
+    self.label  = label
+    self.ncells = numCells
+    return
+
+  def tabulate(self):
+    """
+    Tabulate memory use.
+    """
+    return 2 * self.sizeArrow * self.ncells
+
+if __name__ == '__main__':
+  print 'Memory:',Material('rock', 35).tabulate()


Property changes on: short/3D/PyLith/trunk/pylith/perf/Material.py
___________________________________________________________________
Name: svn:executable
   + *

Added: short/3D/PyLith/trunk/pylith/perf/Memory.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/Memory.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/Memory.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1,12 @@
+class Memory():
+  sizeInt    = 4
+  sizeDouble = 8
+  import distutils.sysconfig
+  pointerSize = distutils.sysconfig.get_config_var('SIZEOF_VOID_P')
+  if pointerSize == 4:
+    sizeArrow = 40 # 32 bit
+  elif pointerSize == 8:
+    sizeArrow = 56 # 64 bit
+  else:
+    raise RuntimeError('Could not determine the size of a pointer')
+

Added: short/3D/PyLith/trunk/pylith/perf/MemoryLogger.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/MemoryLogger.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/MemoryLogger.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1,211 @@
+#!/usr/bin/env python
+#
+# ----------------------------------------------------------------------
+#
+#                           Brad T. Aagaard
+#                        U.S. Geological Survey
+#
+# <LicenseText>
+#
+# ----------------------------------------------------------------------
+#
+
+## @file pylith/perf/MemoryLogger.py
+##
+## @brief Python base class for performance and memory logging.
+##
+## Factory: perf_logger.
+
+from Logger import Logger
+
+# MemoryLogger class
+class MemoryLogger(Logger):
+  """
+  Python base class for performance and memory logging.
+
+  Factory: perf_logger.
+  """
+  
+  # INVENTORY //////////////////////////////////////////////////////////
+
+  class Inventory(Logger.Inventory):
+    """
+    Python object for managing Problem facilities and properties.
+    """
+
+    ## @class Inventory
+    ## Python object for managing Problem facilities and properties.
+    ##
+    ## \b Properties
+    ## @li \b dummy Nothing.
+
+    import pyre.inventory
+
+    dummy = pyre.inventory.bool("dummy", default=True)
+    dummy.meta['tip'] = "Nothing."
+
+  # PUBLIC METHODS /////////////////////////////////////////////////////
+
+  def __init__(self, name="perf_logger"):
+    """
+    Constructor.
+    """
+    Logger.__init__(self, name)
+    self.megabyte     = float(2**20)
+    self.materials    = {}
+    self.vertexGroups = {}
+    return
+
+  def logMesh(self, stage, mesh):
+    """
+    Read mesh parameters to determine memory from our model.
+    """
+    import pylith.perf.Mesh
+    self.mesh = pylith.perf.Mesh.Mesh(mesh.dimension(), mesh.coneSize(), mesh.numVertices(), mesh.numCells())
+    for group, nvertices in mesh.groupSizes():
+      self.logVertexGroup(stage, group, nvertices)
+    if self.verbose:
+      self.tabulate()
+      self.show()
+    return
+
+  def logVertexGroup(self, stage, label, nvertices):
+    """
+    Read vertex group parameters to determine memory from our model.
+    """
+    import pylith.perf.VertexGroup
+    self.vertexGroups[label] = pylith.perf.VertexGroup.VertexGroup(label, nvertices)
+    if self.verbose:
+      self.tabulate()
+      self.show()
+    return
+
+  def logMaterial(self, stage, material):
+    """
+    Read material parameters to determine memory from our model.
+    """
+    import pylith.perf.Material
+    self.materials[material.id()] = pylith.perf.Material.Material(material.label(), material.ncells)
+    if self.verbose:
+      self.tabulate()
+      self.show()
+    return
+
+  def tabulate(self):
+    """
+    Tabulate expected memory usage.
+    """
+    total = 0
+    memory = {}
+    # mesh
+    if hasattr(self, 'mesh'):
+      info = self.mesh.tabulate()
+      memory['mesh'] = info
+      total += sum(info.values())
+    # groups
+    if hasattr(self, 'groups'):
+      memory['groups'] = {}
+      for group in self.groups:
+        nbytes = group.tabulate(self.mesh)
+        total += nbytes
+        memory['groups'][group.label] = nbytes
+    # materials
+    if hasattr(self, 'materials'):
+      memory['materials'] = {}
+      for id, material in self.materials.iteritems():
+        nbytes = material.tabulate()
+        total += nbytes
+        memory['materials'][material.label] = nbytes
+    # Total
+    memory['total'] = total
+    self.memory = memory
+    return
+
+  def join(self, logger):
+    """
+    Incorporate information from another logger.
+    """
+    # mesh
+    memory = logger.memory
+    if 'mesh' in memory:
+      if not 'mesh' in self.memory:
+        self.memory['mesh'] = memory['mesh']
+      else:
+        for key in self.memory['mesh']:
+          self.memory['mesh'][key] += memory['mesh'][key]
+    # groups
+    if 'groups' in memory:
+      if not 'groups' in self.memory:
+        self.memory['groups'] = memory['groups']
+      else:
+        for key in memory['groups']:
+          if not key in self.memory['groups']:
+            self.memory['groups'][key]  = memory['groups'][key]
+          else:
+            self.memory['groups'][key] += memory['groups'][key]
+    # materials
+    if 'materials' in memory:
+      if not 'materials' in self.memory:
+        self.memory['materials'] = memory['materials']
+      else:
+        for key in memory['materials']:
+          if not key in self.memory['materials']:
+            self.memory['materials'][key]  = memory['materials'][key]
+          else:
+            self.memory['materials'][key] += memory['materials'][key]
+    # Total
+    self.memory['total'] += memory['total']
+    return
+
+  def show(self):
+    """
+    Print memory usage.
+    """
+    megabyte = self.megabyte
+    print "MEMORY USAGE"
+    if 'mesh' in self.memory:
+      print "  Finite-element mesh"
+      memory = self.memory['mesh']
+      print "    Mesh:           %d bytes (%.3f MB)" % (memory['mesh'], memory['mesh'] / megabyte)
+      print "    Stratification: %d bytes (%.3f MB)" % (memory['stratification'], memory['stratification'] / megabyte)
+      print "    Coordinates:    %d bytes (%.3f MB)" % (memory['coordinates'], memory['coordinates'] / megabyte)
+      print "    Materials:      %d bytes (%.3f MB)" % (memory['materials'], memory['materials'] / megabyte)
+    if 'groups' in self.memory:
+      print "    Groups"
+      for (label, nbytes) in self.memory['groups'].items():
+        print "      %s: %d bytes (%.3f MB)" % (label, nbytes, nbytes / megabyte)
+    if 'materials' in self.memory:
+      print "  Materials"
+      for (label, nbytes) in self.memory['materials'].items():
+        print "    %s: %d bytes (%.3f MB)" % (label, nbytes, nbytes / megabyte)
+    print "  TOTAL:           %d bytes (%.3f MB)" % (self.memory['total'], self.memory['total'] / megabyte)
+    return
+
+  # PRIVATE METHODS ////////////////////////////////////////////////////
+
+  def _configure(self):
+    """
+    Set members based using inventory.
+    """
+    Logger._configure(self)
+    self.dummy = self.inventory.dummy
+    return
+
+
+  def _setupLogging(self):
+    """
+    Setup event logging.
+    """
+    return
+  
+
+# FACTORIES ////////////////////////////////////////////////////////////
+
+def perf_logger():
+  """
+  Factory associated with Logger.
+  """
+  return MemoryLogger()
+
+
+# End of file 

Added: short/3D/PyLith/trunk/pylith/perf/Mesh.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/Mesh.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/Mesh.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+from Memory import Memory
+
+class Mesh(Memory):
+  cellTypes = {(2,3): 'tri3',
+               (2,4): 'quad4',
+               (3,4): 'tet4',
+               (3,8): 'hex8'
+               }
+
+  """
+  Mesh object for holding mesh memory and performance information.
+  """
+  def __init__(self, dimension = 0, maxConeSize = 0, numVertices = 0, numCells = 0):
+    """
+    Constructor.
+    """
+    self.dimension = dimension
+    self.coneSize  = maxConeSize
+    self.nvertices = numVertices
+    self.ncells    = numCells
+    self.cellType  = None
+    self.initialize()
+    return
+
+  @classmethod
+  def cellTypeInfo(cls, cellType):
+    for k,cT in cls.cellTypes.iteritems():
+      if cT == cellType:
+        return k
+    raise ValueError("Unknown cell type '%s'." % cellType)
+
+  def initialize(self):
+    """
+    Initialize application.
+    """
+    try:
+      self.cellType = self.cellTypes[(self.dimension,self.coneSize)]
+    except:
+      raise ValueError("Unknown cell type '%s' for dim %d and cone size %d." % (self.cellType,self.dimension,self.coneSize))
+    return
+
+  def tabulate(self):
+    """
+    Tabulate memory use.
+    """
+    memory = {'mesh': 0,
+              'stratification': 0,
+              'coordinates': 0,
+              'materials': 0}
+    ncells    = self.ncells
+    nvertices = self.nvertices
+    coneSize  = self.coneSize
+    dimension = self.dimension
+
+    # mesh
+    nbytes = self.sizeInt * (2 * (coneSize*ncells + nvertices + ncells) + coneSize*ncells)
+    memory['mesh'] = nbytes
+
+    # stratification
+    nbytes = 2 * self.sizeArrow * (nvertices + ncells)
+    memory['stratification'] = nbytes
+
+    # coordinates
+    nbytes = self.sizeDouble * dimension * nvertices
+    memory['coordinates'] = nbytes
+
+    # materials
+    nbytes = 2 * self.sizeArrow * ncells
+    memory['materials'] = nbytes
+    return memory
+
+if __name__ == '__main__':
+  print 'Memory:',Mesh(2, 3, 10, 25).tabulate()


Property changes on: short/3D/PyLith/trunk/pylith/perf/Mesh.py
___________________________________________________________________
Name: svn:executable
   + *

Added: short/3D/PyLith/trunk/pylith/perf/VertexGroup.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/VertexGroup.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/VertexGroup.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+from Memory import Memory
+
+class VertexGroup(Memory):
+  """
+  Mesh object for holding vertex group memory and performance information.
+  """
+  def __init__(self, label = '', numVertices = 0):
+    """
+    Constructor.
+    """
+    self.label     = label
+    self.nvertices = numVertices
+    return
+
+  def tabulate(self):
+    """
+    Tabulate memory use.
+    """
+    return self.sizeInt * ( 2 * self.nvertices + self.nvertices)
+
+if __name__ == '__main__':
+  print 'Memory:',VertexGroup('rock', 35).tabulate()

Added: short/3D/PyLith/trunk/pylith/perf/__init__.py
===================================================================
--- short/3D/PyLith/trunk/pylith/perf/__init__.py	                        (rev 0)
+++ short/3D/PyLith/trunk/pylith/perf/__init__.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -0,0 +1 @@
+__all__ = ['Memory', 'Logger', 'MemoryLogger', 'Mesh', 'Material']

Modified: short/3D/PyLith/trunk/pylith/topology/Mesh.py
===================================================================
--- short/3D/PyLith/trunk/pylith/topology/Mesh.py	2009-05-08 17:08:39 UTC (rev 14925)
+++ short/3D/PyLith/trunk/pylith/topology/Mesh.py	2009-05-08 18:26:09 UTC (rev 14926)
@@ -90,6 +90,15 @@
     Return the number of cells.
     """
     return ModuleMesh.numCells(self)
-  
 
+  def groupSizes(self):
+    """
+    Return the name and number of vertices for each group
+    """
+    groups = []
+    names  = ModuleMesh.groups(self)
+    for name in names:
+      groups.append((name,ModuleMesh.groupSize(self, name)))
+    return groups
+
 # End of file



More information about the CIG-COMMITS mailing list