Index: codes/icosagcm/devel/Python/dynamico/__init__.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/__init__.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/__init__.py	(revision 825)
@@ -1,6 +1,0 @@
-# import openmp before NetCDF4 numpy because it uses numpy hence MKL and messes up OMP_NUM_PROCS
-import sys
-if 'numpy' in sys.modules:
-    raise ImportError('Module dynamico must be imported before NetCDF/numpy because numpy may mess up OpenMP')
-import libs
-libs.libicosa.dynamico_show_openmp()
Index: codes/icosagcm/devel/Python/dynamico/dev/__init__.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/__init__.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/dev/__init__.py	(revision 825)
@@ -0,0 +1,6 @@
+# import openmp before NetCDF4 numpy because it uses numpy hence MKL and messes up OMP_NUM_PROCS
+import sys
+if 'numpy' in sys.modules:
+    raise ImportError('Module dynamico must be imported before NetCDF/numpy because numpy may mess up OpenMP')
+import libs
+libs.libicosa.dynamico_show_openmp()
Index: codes/icosagcm/devel/Python/dynamico/dev/libs.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/libs.py	(revision 825)
+++ codes/icosagcm/devel/Python/dynamico/dev/libs.py	(revision 825)
@@ -0,0 +1,2 @@
+from ctypes import cdll
+libxios ,libicosa = [ cdll.LoadLibrary(name) for name in 'libxios.so', 'libicosa.so' ]
Index: codes/icosagcm/devel/Python/dynamico/dev/meshes.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/meshes.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/dev/meshes.py	(revision 825)
@@ -4,6 +4,6 @@
 from dynamico.meshes import Unstructured_PMesh, compute_hybrid_coefs
 from dynamico.meshes import DYNAMICO_Format, MPAS_Format
-from dynamico import unstructured as unst
-from dynamico.dev import numba
+from dynamico.dev import unstructured as unst
+from dynamico.dev import numba, parallel
 from dynamico.dev.numba import int32, float64
 
@@ -25,3 +25,4 @@
 class Cartesian_Mesh(MeshData, meshes.Cartesian_Mesh): pass
 class Unstructured_Mesh(MeshData, meshes.Unstructured_Mesh): pass
-class Local_Mesh(MeshData, meshes.Local_Mesh): pass
+class Local_Mesh(MeshData, meshes.Local_Mesh):
+    Halo_Xchange = parallel.Halo_Xchange # dynamico.dev.parallel instead pf dynamico.parallel
Index: codes/icosagcm/devel/Python/dynamico/dev/parallel.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/parallel.py	(revision 825)
+++ codes/icosagcm/devel/Python/dynamico/dev/parallel.py	(revision 825)
@@ -0,0 +1,9 @@
+from __future__ import absolute_import     
+from __future__ import print_function
+
+from dynamico import parallel
+from dynamico.dev.unstructured import ker
+
+class Halo_Xchange(parallel.Halo_Xchange):
+    def dynamico_init_transfer(self, *args):
+        ker.dynamico_init_transfer(*args)
Index: codes/icosagcm/devel/Python/dynamico/dev/precision.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/precision.py	(revision 825)
+++ codes/icosagcm/devel/Python/dynamico/dev/precision.py	(revision 825)
@@ -0,0 +1,10 @@
+"Helper function to manage mixed precision"
+import numpy as np
+from unstructured import np_num
+
+zero=np_num(0.)
+
+# cast array to float/double depending on CPP_MIXED_PREC
+def asnum(data): return [ x.astype(np_num) for x in data] if type(data) is list else data.astype(np_num)
+
+def zeros(dims): return np.zeros([n for n in dims if n>1], dtype=np_num)
Index: codes/icosagcm/devel/Python/dynamico/dev/wrap.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/wrap.py	(revision 825)
+++ codes/icosagcm/devel/Python/dynamico/dev/wrap.py	(revision 825)
@@ -0,0 +1,78 @@
+#------------------- wrap C/Fortran routines -------------------#                                                                                           
+from dynamico import getargs
+log_master, log_world = getargs.getLogger(__name__)
+INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
+INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug
+
+
+import numpy as np 
+from ctypes import *
+
+class Struct: pass
+
+# converts numpy array to void * for calling C/Fortran routines                                                                                             
+def loc(array): return array.ctypes.data_as(c_void_p)
+
+# defines converter functions depending on type of Python argument
+def noop(x): return x
+py2c = { np.ndarray:loc, np.float64:c_double, np.float32:c_float, int:c_int, 
+         c_void_p:noop, str:noop, c_int:noop }
+
+class Wrap:
+    def __init__(self, fun, check_args, argtypes):
+        fun.restype=None
+        if check_args:
+            fun.argtypes=argtypes
+        self.fun=fun
+        self.convert=None
+    def __call__(self, *args):
+        if self.convert is None:
+            self.convert=[ py2c[type(arg)] for arg in args]
+        args = [ conv(arg) for conv,arg in zip(self.convert,args) ]
+        return self.fun(*args)
+
+def typelist(argtypes):
+    lst=[]
+    for x in argtypes:
+        if type(x) is int:
+            lst+=(x-1)*[prev] # x-1 because prev has already been appended once                                                             
+        else:
+            lst.append(x)
+        prev=x
+    return lst
+
+class SharedLib:
+    def __init__(self,vardict,lib,check_args=True, prefix_so='',prefix_py=''):
+        self.vardict, self.check_args = vardict, check_args
+        self.prefix_so, self.prefix_py = prefix_so, prefix_py
+        self.lib=lib
+        self.vars={}
+    def import_funs(self,prototypes,prefix=''):
+        for proto in prototypes:
+            names=[]
+            while type(proto[0]) is str:
+                names.append(proto.pop(0))
+            if proto[0] is None:
+                proto=None
+            else:
+                proto = typelist(proto)
+            for name in names:
+                name = prefix+name
+                soname = self.prefix_so+name
+                DEBUG('wrap.Sharedlib : importing %s' % soname)
+                self.vardict[self.prefix_py+name] = Wrap(self.lib[soname], self.check_args, proto)
+    def addvars(self,*types_and_names):
+        for x in types_and_names:
+            if type(x) is str:
+                self.vars[x]=ctype.in_dll(self.lib, x.lower())
+            else:
+                ctype = x
+    def getvar(self,name):
+        return self.vars[name].value
+    def getvars(self,*names):
+        return [self.vars[name].value for name in names]
+    def setvar(self,name,val):
+        self.vars[name].value=val
+    def setvars(self,names,vals):
+        for name,val in zip(names,vals):
+            self.vars[name].value=val
Index: codes/icosagcm/devel/Python/dynamico/dev/xios.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/dev/xios.py	(revision 825)
+++ codes/icosagcm/devel/Python/dynamico/dev/xios.py	(revision 825)
@@ -0,0 +1,132 @@
+from __future__ import print_function
+import numpy as np
+import cxios
+from unstructured import ker
+from dynamico.meshes import radian
+from mpi4py import MPI
+
+from dynamico import getargs
+args=getargs.parse()
+log_master, log_world = getargs.getLogger(__name__)
+INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
+INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug
+
+#-----------------------------------------------------------------------------
+
+class Client:
+    def __enter__(self):
+        ker.dynamico_setup_xios()
+        self.comm=MPI.COMM_WORLD # FIXME : we should use the communicator returned by XIOS
+        return self
+    def __exit__(self, type, value, traceback):
+        INFO('xios_finalize()')
+        DEBUG_ALL('xios_finalize')
+        cxios.finalize()
+    def min(self,data): return self.comm.allreduce(data, op=MPI.MIN)
+    def max(self,data): return self.comm.allreduce(data, op=MPI.MAX)
+    
+class Context:
+    def __enter__(self):
+        INFO('cxios.context_close_definition()')
+        cxios.context_close_definition()
+        return self
+    def __exit__(self, type, value, traceback):
+        INFO('xios_context_finalize()')
+        cxios.context_finalize()
+    def init_llm(self, mesh, nqtot):
+        self.mesh=mesh
+        # vertical axis, nq
+        llm = mesh.llm
+        lev, levp1, nq = [cxios.Handle('axis',name) for name in 'lev', 'levp1', 'nq']
+        lev.set_attr(n_glo=llm, value=np.arange(llm))
+        levp1.set_attr(n_glo=llm+1, value=np.arange(llm+1))
+        nq.set_attr(n_glo=nqtot, value=np.arange(nqtot))
+    def init_calendar(self, step):
+        calendar=cxios.Handle('calendar_wrapper')
+        dtime = cxios.Duration(second=step)
+        calendar.set_attr(timestep=dtime)
+        calendar.update_timestep()
+        std=cxios.Handle('fieldgroup','standard_output')
+        std.set_attr(freq_op=dtime)
+        freq_offset = cxios.Duration(second=0)
+        std.set_attr(freq_offset=freq_offset)
+    def update_calendar(self, i):
+        ker.dynamico_xios_update_calendar(i)
+    def send_field_primal(self,name, data):
+        self.send_field(self.mesh.primal_own_loc, name, data)
+    def send_field_dual(self,name, data):
+        self.send_field(self.mesh.dual_own_loc, name, data)
+    def send_field(self,own_loc, name, data):
+        if data.ndim==1:
+            data = data[own_loc]
+        if data.ndim==2:
+            data = data[own_loc,:]
+            data = data.transpose() # XIOS expects contiguous horizontal slices
+        data = np.ascontiguousarray(data)
+        cxios.send_field(name, data)
+
+#-----------------------------------------------------------------------------
+
+def setup_curvilinear(cat,id,nx,ny,own,i_index,j_index,lon,lat):
+    mesh = cxios.Handle(cat,id)
+    def log(name,data) : 
+        DEBUG('setup_curvilinear : %s shape min max %s %s %s'%(name, data.shape, data.min(), data.max()) )
+    i_index, j_index, lon, lat = [ x[own] for x in i_index, j_index, lon, lat ]
+    log('i_index',i_index)
+    log('j_index',j_index)
+    log('lon',lon)
+    log('lat',lat)
+    mesh.set_attr(type='curvilinear', ni_glo=nx, i_index=i_index, nj_glo=ny, j_index=j_index)
+    mesh.set_attr(lonvalue_1d=lon.flatten(), latvalue_1d=lat.flatten())
+
+class Context_Curvilinear(Context):
+    def __init__(self, mesh, nqtot, step):
+        self.init_llm(mesh, nqtot)
+        # primal mesh
+        setup_curvilinear('domaingroup','i', mesh.nx, mesh.ny, mesh.primal_own_loc, 
+                          mesh.primal_i, mesh.primal_j, mesh.lon_i, mesh.lat_i)
+        # dual mesh
+        setup_curvilinear('domaingroup','v', mesh.nx, mesh.ny, mesh.dual_own_loc, 
+                          mesh.dual_i, mesh.dual_j, mesh.lon_v, mesh.lat_v)
+        # calendar
+        self.init_calendar(step)
+
+#-----------------------------------------------------------------------------
+
+def cf_boundaries(degree,points,lon,lat):
+    n, nvertex = len(degree), degree.max()
+    bnd_lon, bnd_lat = np.zeros((n,nvertex)),np.zeros((n,nvertex))
+    for ij in range(n):
+        nb=degree[ij]
+        for k in range(nb):
+            vertex = points[ij,k]
+            bnd_lon[ij,k]=lon[vertex]
+            bnd_lat[ij,k]=lat[vertex]
+        for k in range(nb,nvertex):   # repeat last vertex if nb<nvertex
+            bnd_lon[ij,k]=bnd_lon[ij,nb-1]
+            bnd_lat[ij,k]=bnd_lat[ij,nb-1]
+    return bnd_lon, bnd_lat
+
+def setup_unstructured(cat,id, degree,vertex,lon,lat,lon_v,lat_v, ncell_glo, index_own_glo, displ): # cat in 'domain','domaingroup'
+    # ncell_glo (int) : global number of cells
+    # index_own_glo : global indices of cells own by this MPI process
+    # displ : min of index_own across all MPI processes
+    bnd_lon, bnd_lat = cf_boundaries(degree, vertex, lon_v, lat_v)
+    ncell, nvertex = bnd_lon.shape
+    mesh = cxios.Handle(cat,id)
+    mesh.set_attr(type='unstructured')
+    mesh.set_attr(ni_glo=ncell_glo, ni=ncell, ibegin=displ, i_index=index_own_glo)
+    mesh.set_attr(lonvalue_1d=lon, latvalue_1d=lat)
+    mesh.set_attr(nvertex=nvertex,bounds_lon_1d=bnd_lon, bounds_lat_1d=bnd_lat)
+
+class Context_Unstructured(Context):
+    def __init__(self, pmesh, mesh,nqtot, step):
+        self.init_llm(mesh, nqtot)
+        # primal mesh
+        lon_i, lat_i, lon_v, lat_v = [x*radian for x in mesh.lon_i, mesh.lat_i, mesh.lon_v, mesh.lat_v]
+        setup_unstructured('domaingroup','i', mesh.primal_own_deg, mesh.primal_vertex,
+                           lon_i[mesh.primal_own_loc], lat_i[mesh.primal_own_loc],
+                           lon_v, lat_v,
+                           pmesh.dim_primal.n, mesh.primal_own_glo, mesh.displ)
+        # calendar
+        self.init_calendar(step)
Index: codes/icosagcm/devel/Python/dynamico/kernels.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/kernels.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/kernels.py	(revision 825)
@@ -1,3 +1,3 @@
-from dynamico.precision import zeros
+from dynamico.dev.precision import zeros
 
 def grad(mesh, s_ik):
Index: codes/icosagcm/devel/Python/dynamico/libs.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/libs.py	(revision 824)
+++ 	(revision )
@@ -1,2 +1,0 @@
-from ctypes import cdll
-libxios ,libicosa = [ cdll.LoadLibrary(name) for name in 'libxios.so', 'libicosa.so' ]
Index: codes/icosagcm/devel/Python/dynamico/meshes.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/meshes.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/meshes.py	(revision 825)
@@ -1,2 +1,6 @@
+from __future__ import absolute_import     
+
+from dynamico.dev import unstructured as unst
+
 import time
 import math
@@ -8,10 +12,9 @@
 from matplotlib.collections import PatchCollection
 
-import unstructured as unst
-import parallel
-from util import list_stencil, Base_class, inverse_list
-from precision import zeros
-
-import getargs
+from dynamico import parallel
+from dynamico.util import list_stencil, BaseClass, inverse_list
+from dynamico import getargs
+from dynamico.parmetis import partition_mesh
+
 log_master, log_world = getargs.getLogger(__name__)
 INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
@@ -19,5 +22,5 @@
 
 radian=180/math.pi
-  
+
 #------------------- Hybrid mass-based coordinate -------------
 
@@ -73,4 +76,9 @@
     return [ np.asarray(x) for x in bp_il, mass_dak, mass_dbk ]
 
+#----------------------- Base class for "user" meshes ---------
+
+class BaseMesh(BaseClass):
+    def zeros(self,dims): return np.zeros([n for n in dims if n>1]) # overriden by meshes.dev.DevMesh
+
 #----------------------- Cartesian mesh -----------------------
 
@@ -90,5 +98,5 @@
     return z.transpose()
 
-class Cartesian_Mesh(Base_class):
+class Cartesian_Mesh(BaseMesh):
     def __init__(self,nx,ny,llm,nqdyn,Lx,Ly,f):
         dx,dy = Lx/nx, Ly/ny
@@ -273,11 +281,11 @@
         f.close()
 
-    def field_theta(self,n=1): return zeros((n,self.nqdyn,self.ny,self.nx,self.llm))
-    def field_mass(self,n=1): return zeros((n,self.ny,self.nx,self.llm))
-    def field_z(self,n=1): return zeros((n,self.ny,self.nx,self.llm))
-    def field_w(self,n=1): return zeros((n,self.ny,self.nx,self.llm+1))
-    def field_u(self,n=1): return zeros((n,self.ny,2*self.nx,self.llm))
-    def field_ps(self,n=1): return zeros((n,self.ny,self.nx))
-    def field_ucomp(self,n=1): return zeros((n,self.ny,self.nx,self.llm))
+    def field_theta(self,n=1): return self.zeros((n,self.nqdyn,self.ny,self.nx,self.llm))
+    def field_mass(self,n=1): return self.zeros((n,self.ny,self.nx,self.llm))
+    def field_z(self,n=1): return self.zeros((n,self.ny,self.nx,self.llm))
+    def field_w(self,n=1): return self.zeros((n,self.ny,self.nx,self.llm+1))
+    def field_u(self,n=1): return self.zeros((n,self.ny,2*self.nx,self.llm))
+    def field_ps(self,n=1): return self.zeros((n,self.ny,self.nx))
+    def field_ucomp(self,n=1): return self.zeros((n,self.ny,self.nx,self.llm))
     def ucomp(self,u): 
         return u[range(0,2*self.nx,2),:] if self.ny==1 else u[:,range(0,2*self.nx,2),:]
@@ -293,5 +301,5 @@
 #---------------------- DYNAMICO format for fully unstructured mesh and curvilinear meshes ----------------------
 
-class Mesh_Format(Base_class):
+class Mesh_Format(BaseMesh):
     def getdims(self,*names): return [len(self.nc.dimensions[name]) for name in names]
     def get_pdims(self,comm,*names): return [self.get_pdim(comm,name) for name in names]
@@ -399,16 +407,16 @@
     return ne
 
-class Abstract_Mesh(Base_class):
+class Abstract_Mesh(BaseMesh):
     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))
-    def field_z(self,n=1):     return zeros((n,self.dual_num,self.llm))
-    def field_w(self,n=1):     return zeros((n,self.primal_num,self.llm+1))
-    def field_u(self,n=1):     return zeros((n,self.edge_num,self.llm))
-    def field_ps(self,n=1):    return zeros((n,self.primal_num,))
+    def field_theta(self,n=1): return self.zeros((n,self.nqdyn,self.primal_num,self.llm))
+    def field_mass(self,n=1):  return self.zeros((n,self.primal_num,self.llm))
+    def field_z(self,n=1):     return self.zeros((n,self.dual_num,self.llm))
+    def field_w(self,n=1):     return self.zeros((n,self.primal_num,self.llm+1))
+    def field_u(self,n=1):     return self.zeros((n,self.edge_num,self.llm))
+    def field_ps(self,n=1):    return self.zeros((n,self.primal_num,))
     def ucov2D(self, ulon, ulat): 
         return self.de*(ulon*np.cos(self.angle_e)+ulat*np.sin(self.angle_e))
     def ucov3D(self, ulon, ulat):
-        ucov = zeros((self.edge_num,ulon.shape[1]))
+        ucov = self.zeros((self.edge_num,ulon.shape[1]))
         for edge in range(self.edge_num):
             angle=self.angle_e[edge]
@@ -518,5 +526,6 @@
     def partition_metis(self):
         INFO('Partitioning with ParMetis...')
-        edge_owner = unst.partition_mesh(self.trisk_deg, self.trisk, self.comm.Get_size())
+        edge_owner = partition_mesh(self.comm, self.trisk_deg, self.trisk)
+#        edge_owner = unst.partition_mesh(self.trisk_deg, self.trisk, self.comm.Get_size())
         self.edge_owner = parallel.LocPArray1D(self.dim_edge, edge_owner)
         primal_owner = partition_from_stencil(self.edge_owner, self.primal_deg, self.primal_edge)
@@ -563,4 +572,5 @@
 
 class Local_Mesh(Abstract_Mesh):
+    Halo_Xchange = parallel.Halo_Xchange # overriden in dev.meshes
     def __init__(self, pmesh, llm, nqdyn, mapping):
         comm, dim_primal, primal_owner, dim_edge, edge_owner, dim_dual, dual_owner = pmesh.members(
@@ -620,5 +630,5 @@
         # construct own dual mesh for XIOS output
         dual_own_glo = find_my_cells(dual_owner)
-        dual_own_glo = np.asarray(primal_own_glo, dtype=np.int32)
+        dual_own_glo = np.asarray(dual_own_glo, dtype=np.int32)
         dual_own_loc = [dict_V1[i] for i in dual_own_glo]
         
@@ -655,7 +665,7 @@
         self.to_dynamico()
         # setup halo transfers - NB : llm must be set before we call set_dynamico_transfer
-        self.com_primal = parallel.Halo_Xchange(
+        self.com_primal = self.Halo_Xchange(
             42, dim_primal, cells_C1, get_all_cells(primal_owner))
-        self.com_edges = parallel.Halo_Xchange(
+        self.com_edges = self.Halo_Xchange(
             73, dim_edge, edges_E2, get_all_edges(edge_owner))
         self.com_primal.set_dynamico_transfer('primal')
Index: codes/icosagcm/devel/Python/dynamico/parallel.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/parallel.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/parallel.py	(revision 825)
@@ -10,7 +10,5 @@
         return lst,order  
 
-from unstructured import ker
-
-import getargs
+from dynamico import getargs
 log_master, log_world = getargs.getLogger(__name__)
 INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
@@ -163,6 +161,8 @@
             for x in send_rank, send_len, send_list, recv_rank, recv_len, recv_list ]
         send_list, recv_list = send_list+1, recv_list+1 # Fortran expects that indices start at 1
-        ker.dynamico_init_transfer(index, send_num, send_size, send_rank, send_len, send_list,
+        self.dynamico_init_transfer(index, send_num, send_size, send_rank, send_len, send_list,
                                        recv_num, recv_size, recv_rank, recv_len, recv_list)
+    def dynamico_init_transfer(*args) : pass # overriden in dev.parallel
+
 class LocalArray: # a base class for arrays with halos
     def read_own(self, parray): self.put(self.halo.own_local, self.halo.get_own(parray))
Index: codes/icosagcm/devel/Python/dynamico/precision.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/precision.py	(revision 824)
+++ 	(revision )
@@ -1,10 +1,0 @@
-"Helper function to manage mixed precision"
-import numpy as np
-from unstructured import np_num
-
-zero=np_num(0.)
-
-# cast array to float/double depending on CPP_MIXED_PREC
-def asnum(data): return [ x.astype(np_num) for x in data] if type(data) is list else data.astype(np_num)
-
-def zeros(dims): return np.zeros([n for n in dims if n>1], dtype=np_num)
Index: codes/icosagcm/devel/Python/dynamico/util.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/util.py	(revision 824)
+++ codes/icosagcm/devel/Python/dynamico/util.py	(revision 825)
@@ -7,7 +7,6 @@
             s=stencil[i,j]
             if cond(s): yield stencil[i,j]
-                
 
-class Base_class(object):
+class BaseClass(object):
     def set_members(self, loc, *names):
         for name in names :
Index: codes/icosagcm/devel/Python/dynamico/wrap.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/wrap.py	(revision 824)
+++ 	(revision )
@@ -1,78 +1,0 @@
-#------------------- wrap C/Fortran routines -------------------#                                                                                           
-import getargs
-log_master, log_world = getargs.getLogger(__name__)
-INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
-INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug
-
-
-import numpy as np 
-from ctypes import *
-
-class Struct: pass
-
-# converts numpy array to void * for calling C/Fortran routines                                                                                             
-def loc(array): return array.ctypes.data_as(c_void_p)
-
-# defines converter functions depending on type of Python argument
-def noop(x): return x
-py2c = { np.ndarray:loc, np.float64:c_double, np.float32:c_float, int:c_int, 
-         c_void_p:noop, str:noop, c_int:noop }
-
-class Wrap:
-    def __init__(self, fun, check_args, argtypes):
-        fun.restype=None
-        if check_args:
-            fun.argtypes=argtypes
-        self.fun=fun
-        self.convert=None
-    def __call__(self, *args):
-        if self.convert is None:
-            self.convert=[ py2c[type(arg)] for arg in args]
-        args = [ conv(arg) for conv,arg in zip(self.convert,args) ]
-        return self.fun(*args)
-
-def typelist(argtypes):
-    lst=[]
-    for x in argtypes:
-        if type(x) is int:
-            lst+=(x-1)*[prev] # x-1 because prev has already been appended once                                                             
-        else:
-            lst.append(x)
-        prev=x
-    return lst
-
-class SharedLib:
-    def __init__(self,vardict,lib,check_args=True, prefix_so='',prefix_py=''):
-        self.vardict, self.check_args = vardict, check_args
-        self.prefix_so, self.prefix_py = prefix_so, prefix_py
-        self.lib=lib
-        self.vars={}
-    def import_funs(self,prototypes,prefix=''):
-        for proto in prototypes:
-            names=[]
-            while type(proto[0]) is str:
-                names.append(proto.pop(0))
-            if proto[0] is None:
-                proto=None
-            else:
-                proto = typelist(proto)
-            for name in names:
-                name = prefix+name
-                soname = self.prefix_so+name
-                DEBUG('wrap.Sharedlib : importing %s' % soname)
-                self.vardict[self.prefix_py+name] = Wrap(self.lib[soname], self.check_args, proto)
-    def addvars(self,*types_and_names):
-        for x in types_and_names:
-            if type(x) is str:
-                self.vars[x]=ctype.in_dll(self.lib, x.lower())
-            else:
-                ctype = x
-    def getvar(self,name):
-        return self.vars[name].value
-    def getvars(self,*names):
-        return [self.vars[name].value for name in names]
-    def setvar(self,name,val):
-        self.vars[name].value=val
-    def setvars(self,names,vals):
-        for name,val in zip(names,vals):
-            self.vars[name].value=val
Index: codes/icosagcm/devel/Python/dynamico/xios.py
===================================================================
--- codes/icosagcm/devel/Python/dynamico/xios.py	(revision 824)
+++ 	(revision )
@@ -1,132 +1,0 @@
-from __future__ import print_function
-import numpy as np
-import cxios
-from unstructured import ker
-from dynamico.meshes import radian
-from mpi4py import MPI
-
-import getargs
-args=getargs.parse()
-log_master, log_world = getargs.getLogger(__name__)
-INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
-INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug
-
-#-----------------------------------------------------------------------------
-
-class Client:
-    def __enter__(self):
-        ker.dynamico_setup_xios()
-        self.comm=MPI.COMM_WORLD # FIXME : we should use the communicator returned by XIOS
-        return self
-    def __exit__(self, type, value, traceback):
-        INFO('xios_finalize()')
-        DEBUG_ALL('xios_finalize')
-        cxios.finalize()
-    def min(self,data): return self.comm.allreduce(data, op=MPI.MIN)
-    def max(self,data): return self.comm.allreduce(data, op=MPI.MAX)
-    
-class Context:
-    def __enter__(self):
-        INFO('cxios.context_close_definition()')
-        cxios.context_close_definition()
-        return self
-    def __exit__(self, type, value, traceback):
-        INFO('xios_context_finalize()')
-        cxios.context_finalize()
-    def init_llm(self, mesh, nqtot):
-        self.mesh=mesh
-        # vertical axis, nq
-        llm = mesh.llm
-        lev, levp1, nq = [cxios.Handle('axis',name) for name in 'lev', 'levp1', 'nq']
-        lev.set_attr(n_glo=llm, value=np.arange(llm))
-        levp1.set_attr(n_glo=llm+1, value=np.arange(llm+1))
-        nq.set_attr(n_glo=nqtot, value=np.arange(nqtot))
-    def init_calendar(self, step):
-        calendar=cxios.Handle('calendar_wrapper')
-        dtime = cxios.Duration(second=step)
-        calendar.set_attr(timestep=dtime)
-        calendar.update_timestep()
-        std=cxios.Handle('fieldgroup','standard_output')
-        std.set_attr(freq_op=dtime)
-        freq_offset = cxios.Duration(second=0)
-        std.set_attr(freq_offset=freq_offset)
-    def update_calendar(self, i):
-        ker.dynamico_xios_update_calendar(i)
-    def send_field_primal(self,name, data):
-        self.send_field(self.mesh.primal_own_loc, name, data)
-    def send_field_dual(self,name, data):
-        self.send_field(self.mesh.dual_own_loc, name, data)
-    def send_field(self,own_loc, name, data):
-        if data.ndim==1:
-            data = data[own_loc]
-        if data.ndim==2:
-            data = data[own_loc,:]
-            data = data.transpose() # XIOS expects contiguous horizontal slices
-        data = np.ascontiguousarray(data)
-        cxios.send_field(name, data)
-
-#-----------------------------------------------------------------------------
-
-def setup_curvilinear(cat,id,nx,ny,own,i_index,j_index,lon,lat):
-    mesh = cxios.Handle(cat,id)
-    def log(name,data) : 
-        DEBUG('setup_curvilinear : %s shape min max %s %s %s'%(name, data.shape, data.min(), data.max()) )
-    i_index, j_index, lon, lat = [ x[own] for x in i_index, j_index, lon, lat ]
-    log('i_index',i_index)
-    log('j_index',j_index)
-    log('lon',lon)
-    log('lat',lat)
-    mesh.set_attr(type='curvilinear', ni_glo=nx, i_index=i_index, nj_glo=ny, j_index=j_index)
-    mesh.set_attr(lonvalue_1d=lon.flatten(), latvalue_1d=lat.flatten())
-
-class Context_Curvilinear(Context):
-    def __init__(self, mesh, nqtot, step):
-        self.init_llm(mesh, nqtot)
-        # primal mesh
-        setup_curvilinear('domaingroup','i', mesh.nx, mesh.ny, mesh.primal_own_loc, 
-                          mesh.primal_i, mesh.primal_j, mesh.lon_i, mesh.lat_i)
-        # dual mesh
-        setup_curvilinear('domaingroup','v', mesh.nx, mesh.ny, mesh.dual_own_loc, 
-                          mesh.dual_i, mesh.dual_j, mesh.lon_v, mesh.lat_v)
-        # calendar
-        self.init_calendar(step)
-
-#-----------------------------------------------------------------------------
-
-def cf_boundaries(degree,points,lon,lat):
-    n, nvertex = len(degree), degree.max()
-    bnd_lon, bnd_lat = np.zeros((n,nvertex)),np.zeros((n,nvertex))
-    for ij in range(n):
-        nb=degree[ij]
-        for k in range(nb):
-            vertex = points[ij,k]
-            bnd_lon[ij,k]=lon[vertex]
-            bnd_lat[ij,k]=lat[vertex]
-        for k in range(nb,nvertex):   # repeat last vertex if nb<nvertex
-            bnd_lon[ij,k]=bnd_lon[ij,nb-1]
-            bnd_lat[ij,k]=bnd_lat[ij,nb-1]
-    return bnd_lon, bnd_lat
-
-def setup_unstructured(cat,id, degree,vertex,lon,lat,lon_v,lat_v, ncell_glo, index_own_glo, displ): # cat in 'domain','domaingroup'
-    # ncell_glo (int) : global number of cells
-    # index_own_glo : global indices of cells own by this MPI process
-    # displ : min of index_own across all MPI processes
-    bnd_lon, bnd_lat = cf_boundaries(degree, vertex, lon_v, lat_v)
-    ncell, nvertex = bnd_lon.shape
-    mesh = cxios.Handle(cat,id)
-    mesh.set_attr(type='unstructured')
-    mesh.set_attr(ni_glo=ncell_glo, ni=ncell, ibegin=displ, i_index=index_own_glo)
-    mesh.set_attr(lonvalue_1d=lon, latvalue_1d=lat)
-    mesh.set_attr(nvertex=nvertex,bounds_lon_1d=bnd_lon, bounds_lat_1d=bnd_lat)
-
-class Context_Unstructured(Context):
-    def __init__(self, pmesh, mesh,nqtot, step):
-        self.init_llm(mesh, nqtot)
-        # primal mesh
-        lon_i, lat_i, lon_v, lat_v = [x*radian for x in mesh.lon_i, mesh.lat_i, mesh.lon_v, mesh.lat_v]
-        setup_unstructured('domaingroup','i', mesh.primal_own_deg, mesh.primal_vertex,
-                           lon_i[mesh.primal_own_loc], lat_i[mesh.primal_own_loc],
-                           lon_v, lat_v,
-                           pmesh.dim_primal.n, mesh.primal_own_glo, mesh.displ)
-        # calendar
-        self.init_calendar(step)
Index: codes/icosagcm/devel/Python/src/cxios.pyx
===================================================================
--- codes/icosagcm/devel/Python/src/cxios.pyx	(revision 824)
+++ codes/icosagcm/devel/Python/src/cxios.pyx	(revision 825)
@@ -1,4 +1,4 @@
-from dynamico.libs import libxios
-import dynamico.wrap as wrap
+from dynamico.dev.libs import libxios
+from dynamico.dev import wrap
 import numpy as np
 
@@ -7,5 +7,5 @@
 c_void_p_byref=type(byref(c_void_p())) # used in py2c because byref creates an object of this type, not c_void_pp
 
-import getargs
+from dynamico import getargs
 log_master, log_world = getargs.getLogger(__name__)
 INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
Index: codes/icosagcm/devel/Python/src/unstructured.pyx
===================================================================
--- codes/icosagcm/devel/Python/src/unstructured.pyx	(revision 824)
+++ codes/icosagcm/devel/Python/src/unstructured.pyx	(revision 825)
@@ -1,7 +1,7 @@
 import time
 import math
-import wrap
-from libs import libicosa
-from util import list_stencil
+from dynamico.dev import wrap
+from dynamico.dev.libs import libicosa
+from dynamico.util import list_stencil
 
 from ctypes import c_void_p, c_int, c_double, c_float, c_bool
@@ -10,5 +10,5 @@
 import numpy as np
 
-import getargs
+from dynamico import getargs
 log_master, log_world = getargs.getLogger(__name__)
 INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
Index: codes/icosagcm/devel/Python/test/py/Baroclinic_3D_ullrich.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/Baroclinic_3D_ullrich.py	(revision 824)
+++ codes/icosagcm/devel/Python/test/py/Baroclinic_3D_ullrich.py	(revision 825)
@@ -30,12 +30,12 @@
 INFO, DEBUG, DEBUG_ALL, ERROR = log_master.info, log_master.debug, log_world.debug, log_world.error
 
-from dynamico import unstructured as unst
+from dynamico.dev import unstructured as unst
+from dynamico.dev import meshes
+from dynamico.dev import xios
+from dynamico.dev import precision as prec
 from dynamico import dyn
 from dynamico import time_step
 from dynamico import DCMIP
-from dynamico import meshes
 from dynamico import maps
-from dynamico import xios
-from dynamico import precision as prec
 from dynamico.kernels import grad, curl, div, KE
 from dynamico.LAM import Davies
Index: codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py	(revision 824)
+++ codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py	(revision 825)
@@ -25,5 +25,5 @@
 
 INFO('Loading DYNAMICO modules ...')
-from dynamico import unstructured as unst
+from dynamico.dev import unstructured as unst
 from dynamico.dev.meshes import MPAS_Format, Unstructured_PMesh as PMesh, Local_Mesh as Mesh
 from dynamico.dev import meshes
Index: codes/icosagcm/devel/Python/test/py/dump_partition.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/dump_partition.py	(revision 824)
+++ codes/icosagcm/devel/Python/test/py/dump_partition.py	(revision 825)
@@ -16,4 +16,5 @@
 
 args = getargs.parse()
+for arg in vars(args): print arg, getattr(args, arg)
 
 log_master, log_world = getargs.getLogger()
@@ -29,5 +30,5 @@
 
 INFO('Loading DYNAMICO modules ...')
-from dynamico import unstructured as unst
+from dynamico.dev import unstructured as unst
 from dynamico.dev.meshes import MPAS_Format, Unstructured_PMesh as PMesh, Local_Mesh as Mesh
 from dynamico.dev import meshes
@@ -140,6 +141,5 @@
                     ("primal_own_deg","f8",self._mesh.primal_own_deg),
                     ("primal_own_glo","f8",self._mesh.primal_own_glo),
-                    ("primal_own_loc","f8",self._mesh.primal_own_loc),
-                    ("dual_own_loc","f8",self._mesh.dual_own_loc) ])
+                    ("primal_own_loc","f8",self._mesh.primal_own_loc) ])
     
         self.create_vars(f,("primal_cell","primal_edge_or_vertex"),
@@ -156,5 +156,6 @@
                     ("lat_v","f8",self._mesh.lat_v),
                     ("ref_lat_v","f8",self._mesh.ref_lat_v),
-                    ("vertices_V1","f8",self._mesh.vertices_V1) ])
+                    ("vertices_V1","f8",self._mesh.vertices_V1),
+                    ("dual_own_loc","f8",self._mesh.dual_own_loc)  ])
     
         self.create_vars(f,("dual_cell","dual_edge_or_vertex"),
Index: codes/icosagcm/devel/Python/test/py/partition.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/partition.py	(revision 824)
+++ codes/icosagcm/devel/Python/test/py/partition.py	(revision 825)
@@ -1,3 +1,9 @@
 print 'Starting'
+
+from dynamico import meshes
+from dynamico import parallel
+from dynamico.dev import unstructured as unst
+from dynamico import maps
+from dynamico.parmetis import partition_graph
 
 from mpi4py import MPI
@@ -7,6 +13,4 @@
 
 #from dynamico import partition
-from dynamico import parallel, meshes
-from dynamico import unstructured as unst
 
 import math as math
@@ -46,8 +50,9 @@
     part = 0*xadj_loc[0:-1];
 
-    unst.ker.dynamico_partition_graph(mpi_rank, mpi_size, vtxdist, xadj_loc, adjncy_loc, 4, part)
+#    unst.ker.dynamico_partition_graph(mpi_rank, mpi_size, vtxdist, xadj_loc, adjncy_loc, 4, part)
+    partition_graph(comm, vtxdist, xadj_loc, adjncy_loc, part, nparts=4)
 
-#    for i in range(len(part)):
-#        print 'vertex', i+idx_start, 'proc', part[i]
+    for i in range(len(part)):
+        print 'vertex', i+idx_start, 'proc', part[i]
 
 #-----------------------------------------------------------------------------#
@@ -84,5 +89,6 @@
 def coriolis(lon,lat): return 0.*lat
 llm, nqdyn, radius = 1,1,1.
-lmesh = meshes.Local_Mesh(pmesh, llm, nqdyn, radius, coriolis)
+planet = maps.SphereMap(radius, 0.)
+lmesh = meshes.Local_Mesh(pmesh, llm, nqdyn, planet)
 
 (primal_deg, primal_vertex, dim_vertex, dim_cell, cell_owner, 
Index: codes/icosagcm/devel/Python/test/py/write_Cartesian_mesh.py
===================================================================
--- codes/icosagcm/devel/Python/test/py/write_Cartesian_mesh.py	(revision 824)
+++ codes/icosagcm/devel/Python/test/py/write_Cartesian_mesh.py	(revision 825)
@@ -14,6 +14,6 @@
 
 args = getargs.parse()
+for arg in vars(args): print arg, getattr(args, arg)
 
-from dynamico.meshes import zeros
 from dynamico import meshes
 import numpy as np
Index: codes/icosagcm/devel/Python/test/python.sh
===================================================================
--- codes/icosagcm/devel/Python/test/python.sh	(revision 824)
+++ codes/icosagcm/devel/Python/test/python.sh	(revision 825)
@@ -21,5 +21,5 @@
     shift
     rm -f xios_client*.*
-    mpirun -np $NB_MPI python -u $* 2>&1 | tee dynamico.log
+    mpirun --mca mpi_warn_on_fork 0 -np $NB_MPI python -u $* 2>&1 | tee dynamico.log
 }
 
@@ -29,5 +29,6 @@
 cd $DYNAMICO_ROOT
 
-cp -i -u -r Python/dynamico/* lib/dynamico/
+cp -i -u Python/dynamico/*.py lib/dynamico/
+cp -i -u Python/dynamico/dev/*.py lib/dynamico/dev/
 
 . arch.env
