Index: codes/icosagcm/devel/Python/dynamico/dev/meshes.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/meshes.py	(revision 804)
+++ codes/icosagcm/devel/Python/dynamico/dev/meshes.py	(revision 805)
@@ -2,12 +2,25 @@
 
 from dynamico import meshes
-from dynamico.meshes import MPAS_Format
-from dynamico.dev.numba import int32, float64, store_data
+from dynamico.meshes import MPAS_Format, Unstructured_PMesh, compute_hybrid_coefs
+from dynamico import unstructured as unst
+from dynamico.dev import numba
+from dynamico.dev.numba import int32, float64
 
-class Unstructured_Mesh(meshes.Unstructured_Mesh):
-    def get_data(self):
-        return store_data(self,
-                   int32,      'primal_num dual_num edge_num',
-                   int32[:],   'primal_deg left right',
-                   int32[:,:], 'primal_edge primal_ne',
-                   float64[:], 'le_de Ai')
+class MeshData(numba.NumbaData):
+    signature=(int32,      'primal_num dual_num edge_num',
+               int32[:],   'primal_deg left right',
+               int32[:,:], 'primal_edge primal_ne',
+               float64[:], 'le_de le de lon_e lat_e Ai')
+    def to_dynamico(self):
+        max_primal_deg, max_dual_deg, max_trisk_deg = [x.shape[1] for x in self.primal_edge, self.dual_edge, self.trisk]
+        unst.init_mesh(self.llm, self.nqdyn, self.edge_num, self.primal_num, self.dual_num,
+                  max_trisk_deg, max_primal_deg, max_dual_deg,
+                  self.primal_deg, self.primal_edge, self.primal_ne,
+                  self.dual_deg, self.dual_edge, self.dual_ne, self.dual_vertex,
+                  self.left, self.right, self.down, self.up, self.trisk_deg, self.trisk,
+                  self.Ai, self.Av, self.fv, self.le_de, self.Riv2, self.wee)
+
+# note inheritance order : inherit first from DevMesh to override empty to_dynamico() from AbstractMesh
+class Cartesian_Mesh(MeshData, meshes.Cartesian_Mesh): pass
+class Unstructured_Mesh(MeshData, meshes.Unstructured_Mesh): pass
+class Local_Mesh(MeshData, meshes.Local_Mesh): pass
Index: codes/icosagcm/devel/Python/dynamico/dev/numba.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/numba.py	(revision 804)
+++ codes/icosagcm/devel/Python/dynamico/dev/numba.py	(revision 805)
@@ -6,18 +6,20 @@
 import numba
 
-def store_data(obj,*args):
-    """Returns a jitclass instance containing attributes copied from obj. *args is of the form type,names,type,names ... where names is a string 'attr1 attr2 attr3' containing space-separated names of attributes of obj. Those attributes are declared to numba with the type preceding them. The result of store_data can be used as argument to a @jit function."""
-    spec = []
-    for item in args:
-        if isinstance(item,str): 
-            spec = spec + [(name,thetype) for name in item.split(' ')]
-        else:
-            thetype=item
-    @numba.jitclass(spec)
-    class JitClass(object):
-        def __init__(self): pass
-    data=JitClass()
-    for name,thetype in spec: setattr(data, name, getattr(obj,name))
-    return data
+class NumbaData(object):
+    """A base class to extract data from derived class instances and use it as argument to @jit functions. Derived classes must set the 'signature' attribute."""
+    def data(self):
+        """Returns a jitclass instance containing attributes copied from self, using self.signature which is of the form type,names,type,names ... where names is a string 'attr1 attr2 attr3' containing space-separated names of attributes of self. Those attributes are declared to numba with the type preceding them. The result of data() can be used as argument to a @jit function."""
+        spec = []
+        for item in self.signature:
+            if isinstance(item,str): 
+                spec = spec + [(name,thetype) for name in item.split(' ')]
+            else:
+                thetype=item
+        @numba.jitclass(spec)
+        class JitClass(object):
+            def __init__(self): pass
+        data=JitClass()
+        for name,thetype in spec: setattr(data, name, getattr(self,name))
+        return data
 
 jit=numba.jit(nopython=True, nogil=True, error_model='numpy', fastmath=True)
Index: codes/icosagcm/devel/Python/dynamico/meshes.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/meshes.py	(revision 804)
+++ codes/icosagcm/devel/Python/dynamico/meshes.py	(revision 805)
@@ -90,5 +90,5 @@
     return z.transpose()
 
-class Cartesian_mesh(Base_class):
+class Cartesian_Mesh(Base_class):
     def __init__(self,nx,ny,llm,nqdyn,Lx,Ly,f):
         dx,dy = Lx/nx, Ly/ny
@@ -115,4 +115,6 @@
         def zeros(shape,n=1): return [np.zeros(shape) for i in range(n)] if n>1 else np.zeros(shape)
         def indices(shape,n=1): return [np.zeros(shape,np.int32) for i in range(n)] if n>1 else np.zeros(shape,np.int32)
+
+        primal_num, dual_num, edge_num = nx*ny, nx*ny, 2*nx*ny
 
         Aiv, lon_i,lon_v,lat_i,lat_v   = zeros( nx*ny,   5)
@@ -178,18 +180,17 @@
 
         Aiv[:]=dx*dy # Ai=Av=dx*dy
-        le_de=le/de
-        unst.init_mesh(llm,nqdyn,2*nx*ny,nx*ny,nx*ny,4,4,4,
-                  primal_deg,primal_edge,primal_ne,
-                  dual_deg,dual_edge,dual_ne,dual_vertex,
-                  left,right,down,up,trisk_deg,trisk,
-                  Aiv,Aiv,f+0.*Aiv,le_de,Riv2,wee)
-        self.set_members(locals(), 'primal_deg', 'primal_edge', 'primal_ne', 'primal_vertex',
+        le_de, fv = le/de, f+0.*Aiv
+        
+        self.set_members(locals(), 'primal_num',  'dual_num', 'edge_num',
+                         'primal_deg', 'primal_edge', 'primal_ne', 'primal_vertex',
                          'dual_deg', 'dual_edge', 'dual_ne', 'dual_vertex',
                          'left','right','down','up',
                          'trisk_deg','trisk','Riv2','wee',
-                         'lon_i','lat_i','lon_v','lat_v',
+                         'lon_i','lat_i','lon_v','lat_v', 'fv',
                          'le_de','le','de','lon_e','lat_e','angle_e',
                          'primal_i','primal_j','edge_i','edge_j')
         self.Ai, self.Av = Aiv, Aiv
+        self.to_dynamico()
+    def to_dynamico(self): pass
     def ncwrite(self, name):
         """The method writes Cartesian mesh on the disc.
@@ -399,4 +400,5 @@
 
 class Abstract_Mesh(Base_class):
+    def to_dynamico(self): pass
     def field_theta(self,n=1): return zeros((n,self.nqdyn,self.primal_num,self.llm))
     def field_mass(self,n=1):  return zeros((n,self.primal_num,self.llm))
@@ -436,5 +438,5 @@
         self.lon_v, self.lat_v = mapping.map(self.lon_v, self.lat_v)
         self.lon_e, self.lat_e = mapping.map(self.lon_e, self.lat_e)
-    
+
 class Unstructured_Mesh(Abstract_Mesh):
     def __init__(self, gridfile, llm, nqdyn, radius, f):
@@ -466,16 +468,10 @@
                          'primal_num', 'dual_num', 'edge_num', 'primal_deg', 'primal_vertex', 'primal_ne',
                          'lat_i', 'lon_i', 'lat_v', 'lon_v', 'lat_e', 'lon_e', 'angle_e',
-                         'Ai', 'Av', 'fv', 'le', 'de', 'le_de',
+                         'Ai', 'Av', 'fv', 'le', 'de', 'down', 'up', 'le_de',
                          'trisk_deg', 'trisk', 'wee', 'Riv2', 'dual_ne',
                          'left', 'right',
                          'primal_edge')
         gridfile.normalize(self)
-        max_primal_deg, max_dual_deg, max_trisk_deg = [ x.shape[1] for x in primal_edge, dual_edge, trisk]
-        unst.init_mesh(llm, nqdyn, edge_num, primal_num,dual_num,
-                  max_trisk_deg, max_primal_deg, max_dual_deg,
-                  primal_deg,primal_edge,primal_ne,
-                  dual_deg,dual_edge,dual_ne,dual_vertex,
-                  left,right,down,up,trisk_deg,trisk,
-                  self.Ai,self.Av,self.fv,le_de,Riv2,wee)
+        self.to_dynamico()
         self.primal  = tri.Triangulation(lon_i*radian, lat_i*radian)
         self.dual    = tri.Triangulation(lon_v*radian, lat_v*radian)
@@ -604,5 +600,4 @@
         for edge in range(edge_num): 
             if edge_deg[edge]<2: up[edge]=down[edge]
-        max_primal_deg, max_dual_deg, max_trisk_deg = [x.shape[1] for x in primal_edge, dual_edge, trisk]
 
         # construct own primal mesh for XIOS output
@@ -638,5 +633,6 @@
                          'trisk_deg', 'trisk', 'wee',
                          'dual_deg', 'dual_edge', 'dual_ne', 'dual_vertex', 'Riv2',
-                         'left','right','primal_deg','primal_edge','primal_ne',
+                         'left', 'right', 'down', 'up', 
+                         'primal_deg', 'primal_edge', 'primal_ne',
                          'vertices_V1', 'edges_E2',
                          'lon_i', 'lat_i', 'Ai',
@@ -651,11 +647,5 @@
         self.fv = mapping.coriolis(self.lon_v,self.lat_v) # Coriolis parameter
         # propagate info to Fortran side
-        unst.init_mesh(llm, nqdyn, self.edge_num, self.primal_num, self.dual_num,
-                  max_trisk_deg, max_primal_deg, max_dual_deg,
-                  primal_deg,primal_edge,primal_ne,
-                  dual_deg,dual_edge,dual_ne,dual_vertex,
-                  left,right,down,up,trisk_deg,trisk,
-                  self.Ai,self.Av,self.fv,self.le_de,self.Riv2,self.wee)
-
+        self.to_dynamico()
         # setup halo transfers - NB : llm must be set before we call set_dynamico_transfer
         self.com_primal = parallel.Halo_Xchange(
@@ -767,5 +757,5 @@
     return bounds
 
-class Stencil_glob:
+class Stencil_glob(object):
     def __init__(self, degree, neigh, weight=None):
         self.degree, self.neigh, self.weight = degree, neigh, weight
@@ -773,5 +763,5 @@
         return Stencil(cells, self.degree, self.neigh, neigh_dict, self.weight)
             
-class Stencil:
+class Stencil(object):
     def __init__(self, cells, degree, neigh, neigh_dict, weight=None):
         get = degree.dim.getter(cells)
Index: codes/icosagcm/devel/Python/test/py/Godunov.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/Godunov.py	(revision 804)
+++ codes/icosagcm/devel/Python/test/py/Godunov.py	(revision 805)
@@ -72,5 +72,5 @@
 flux = mesh.field_u()
 
-mesh_data = mesh.get_data()
+mesh_data = mesh.data()
 
 for i in range(N):    
Index: codes/icosagcm/devel/Python/test/py/NH_3D_bubble.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/NH_3D_bubble.py	(revision 804)
+++ codes/icosagcm/devel/Python/test/py/NH_3D_bubble.py	(revision 805)
@@ -3,7 +3,7 @@
 from dynamico import time_step
 from dynamico import DCMIP
-from dynamico import meshes
+from dynamico.dev import meshes
 from dynamico import precision as prec
-from dynamico.meshes import Cartesian_mesh as Mesh
+from dynamico.dev.meshes import Cartesian_Mesh as Mesh
 import math as math
 import matplotlib.pyplot as plt
Index: codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py	(revision 804)
+++ codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py	(revision 805)
@@ -13,5 +13,5 @@
 INFO('Loading DYNAMICO modules ...')
 from dynamico import unstructured as unst
-from dynamico.meshes import MPAS_Format, Unstructured_PMesh as PMesh, Local_Mesh as Mesh
+from dynamico.dev.meshes import MPAS_Format, Unstructured_PMesh as PMesh, Local_Mesh as Mesh
 from dynamico import time_step
 from dynamico import maps
